实验五 子程序结构的设计方法
专业:材料物理; 姓名:曾瑞; 学号:2011301230019
1,实验内容
编程计算N!,从键盘上接受10以内的数,计算出其阶乘后在屏幕显示结果;
2,实验要求
用子程序编写计算N!的代码以及结果显示代码;
3,实验目的
学习子程序结构,了解子程序的调用、返回的过程,掌握其编程的方法;
4,程序流程图
5,源程序
;FILENAME ZENG.ASM
DATA SEGMENT
MESG1 DB 'PLEASE INPUT A NUMBER BETWEEN 0 AND 9',0DH,0AH,'$'
MESG2 DB ' ERROR MESSAGE!',0DH,0AH,'$'
MESG3 DB '!=','$'
STORE DW ?
DATA ENDS
STACK SEGMENT
DB 256 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
MAIN PROC FAR
START: MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET MESG1 ;输出提示语句
MOV AH,09H
INT 21H
MOV AH,1 ;键盘输入一个字符并回显
INT 21H
CMP AL,20H ;如果输入的是空格,则返回
JZ EXIT
XOR AL,30H ;将ASCII码转换成二进制数
CMP AL,0 ;将AL中数与0比较
JNZ NEXT
INC AL ;若为0,则加一
NEXT: CMP AL,9 ;与9进行比较
JA ERROR ;若大于9,则跳转
PUSH AX ;将AX中内容堆栈,保护输入数
LEA DX,MESG3
MOV AH,09H
INT 21H
POP AX
CALL CALCUL
CALL PRINT
CALL CRLF
JMP START
ERROR: MOV DX,OFFSET MESG2 ;输出提示信息,提醒输入有误
MOV AH,09H
INT 21H
JMP START
EXIT: MOV AH,4CH
INT 21H
MAIN ENDP
CALCUL PROC
MOV AH,0
MOV CX,AX ;CX存放输入的数字
MOV AL,1 ;将AX初始值赋1
MOV DX,0
MOV BX,0
AGAIN: INC BX
MUL BX
CMP BX,CX
JNZ AGAIN ;若BX小于CX,则循环执行
RET
CALCUL ENDP
PRINT PROC
MOV CX,0
CMP DX,0 ;将DX中内容与0比较
JZ THEN
MOV BX,10
DIV BX
PUSH DX
INC CX
THEN: MOV DX,0
MOV [STORE],AX ;[STORE]是个字单元,在数据段已
MOV BX,10 ;有定义
DIV BX
PUSH DX ;将余数堆栈
INC CX ;CX当计数器,存放堆栈的次数
CMP DX,[STORE]
JNZ THEN ;若余数与被除数不等,继续循环
DISPLAY: POP DX ;出栈,把数据赋给DX
ADD DL,30H ;DL存放欲显示数的ASCII码
MOV AH,2
INT 21H
LOOP DISPLAY
RET
PRINT ENDP
CRLF PROC
MOV DL,0DH ;显示回车与换行
MOV AH,2
INT 21H
MOV DL,0AH
MOV AH,2
INT 21H
RET
CRLF ENDP
CODE ENDS
END MAIN
5,实验结果及分析
(1)程序运行结果如下:
PLEASE INPUT A NUMBER BETWEEN 0 AND 9
0!=1
PLEASE INPUT A NUMBER BETWEEN 0 AND 9
1!=1
PLEASE INPUT A NUMBER BETWEEN 0 AND 9
2!=2
PLEASE INPUT A NUMBER BETWEEN 0 AND 9
3!=6
PLEASE INPUT A NUMBER BETWEEN 0 AND 9
4!=24
PLEASE INPUT A NUMBER BETWEEN 0 AND 9
5!=120
PLEASE INPUT A NUMBER BETWEEN 0 AND 9
6!=720
PLEASE INPUT A NUMBER BETWEEN 0 AND 9
7!=5040
PLEASE INPUT A NUMBER BETWEEN 0 AND 9
8!=40320
PLEASE INPUT A NUMBER BETWEEN 0 AND 9
9!=362880
PLEASE INPUT A NUMBER BETWEEN 0 AND 9
H ERROR MESSAGE!
注意:当输入其他字符时,比如H,则显示‘ERROR MESSAGE!’
(2)需要说明的有以下几点:
① 用INT 21H指令执行功能调用会影响AX中的数据,因此在调用前必须将AX中的数据进行堆栈操作。在本实验中遇到的问题之一即在此:由于在之前没有将AX中的数据进行堆栈保护,运用INT 21H功能后,AL变成了24H,结果最后所有的输出都变成了0;
② 实验过程中遇见的另外一个问题是,1—8的阶乘都显示正常,只有9的阶乘有问题,显示为35200。原因是先前的循环体部分是:
AGAIN: MUL CX
LOOP AGAIN
其运行方式为CX减1后参与乘法运算,这种方式对于1-8的阶乘计算没有问题,因为8!=40320<65535,而当9*8*……*3=181440>65535,此时DX存放了0002H,AX存放了C4C0H;对AX做乘法运算(乘以2)后,DX位存放0001H,AX存放8980H;对AX做乘法运算(乘以1)后,DX位为0000H,AX为8980H,因此结果为35200。为了避免出现上述的情况,将运行方式改为1*2*3……*9的方式,即递增的方式,当1*2*3……*9时,DX存放0005H,AX存放8980H,因此最终结果才为362880;
③在本程序PRINT过程中采用了循环除10的方法,获得各位整数,而且采用了堆栈——出栈的方式,实现了高位到低位数的输出。这不仅比采用“除10000,再除1000,……”的方法在程序上要简洁,而且输出结果也要简洁,比如前者6!=720,后者的6!=00720。
第二篇:C实验报告:选择结构程序设计
C语言实验报告
课程__C程序设计_实验名称_选择结构程序设计__第 页 共 页
系 别__电气工程______________________ 实 验 日 期 20## 年 4 月 14日
专业班级___ 自动化 __2班 _______________ 实 验 报 告 日 期 20## 年 4月 14日
姓 名___马震_________学号_P091813232___ 报 告 退 发 ( 订正 、 重做 )
教 师 审 批 签 字
一. 实验目的
If结构的练习
二. 实验内容
(-)实验题目一:给出一百分制成绩,要求输出成绩等级`A`、`B`、`C`、`D`、`E`。90分以上为`A`,80~89分为`B`,70~79分为`C`,60~69分为`D`,60分以下为`E`。
1.要点分析
见右图
2.实验步骤
#include <stdio.h>
void main()
{
int x;
printf("请输入一个百分制分数,按回车键结束\n");
scanf("%d",&x);
printf("该分数的等级为");
if(x>=90) printf("A\n");
else if(x>=80) printf("B\n");
else if(x>=70) printf("C\n");
else if(x>=60) printf("D\n");
else printf("E\n"); }
3. 实验结果
(二)实验题目二:给一个不多于五位的正整数,要求:1.求出它是几位数2.分别输出每一位数字3.按逆序输出各位数字
1.要点分析
见右侧图
2.实验步骤
#include <stdio.h>
void main()
{ int x,a,b,c,d,e;
printf("请输入一个不多于5位的正整数\n");
scanf("%d",&x);
if(x/10000>0)
{a=x/10000;
b=x/1000-a*10;
c=x/100-a*100-b*10;
d=x/10-a*1000-b*100-c*10;
e=x-a*10000-b*1000-c*100-d*10;
printf("%d,%d,%d,%d,%d\n",a,b,c,d,e);
printf("按逆序输出数字为%d%d%d%d%d\n",e,d,c,b,a);}
else if(x/1000>0)
{a=x/1000;
b=x/100-a*10;
c=x/10-a*100-b*10;
d=x-a*1000-b*100-c*10;
printf("%d,%d,%d,%d\n",a,b,c,d);
printf("按逆序输出数字为%d%d%d%d\n",d,c,b,a);}
else if(x/100>0)
{a=x/100;
b=x/10-a*10;
c=x/-a*100-b*10;
printf("%d,%d,%d\n",a,b,c);
printf("按逆序输出数字为%d%d%d\n",c,b,a);}
else if(x/10>0)
{a=x/10;
b=x-a*10;
printf("%d,%d\n",a,b);
printf("按逆序输出数字为%d%d\n",b,a);}
else
{a=x;
printf("%d\n",a);
printf("按逆序输出数字为%d\n",a);}}
3.实验结果
(三)实验题目三:企业发放的奖金根据利润提成。利润I低于或等于10万元的,奖金提10%;利润高于10万元,低于20万元(100000<I≤200000)时,低于10万元的部分按10%,高于10万的部分,可提成7.5%;200000<I≤400000元时,低于20万的仍按上述办法提成(下同)。高于20万的部分按5%提成;400000<I≤600000元时,高于40万的按3%提成;600000<I≤1000000时,高于60万的按1.5%提成;1000000<I时,超过100万的按1%提成。从键盘输入当月利润I,求应发奖金总数。要求用IF语句编程序。
1.要点分析
见右侧图
2.实验步骤
#include <stdio.h>
void main()
{long x,y;
printf("请输入当月利润\n");
scanf("%ld",&x);
printf("发放奖金总数为");
if(x<=100000)
{y=0.1*x;printf("%ld\n",y);}
else if(x<=200000)
{x=x-100000;y=10000+0.075*x;printf("%ld\n",y);}
else if(x<=400000)
{x=x-200000;y=17500+x*0.05;printf("%ld\n",y);}
else if(x<=600000)
{x=x-400000;y=27500+x*0.03;printf("%ld\n",y);}
else if(x<=1000000)
{x=x-600000;y=33500+x*0.015;printf("%ld\n",y);}
else {x=x-1000000;y=39500+x*0.01;printf("%ld\n",y);}}
实验结果
个人小结
本次试验内容为很简单基础的If语句使用…有利于及时复习所学过的知识…由写试验报告的时间大于编程时间可得:这次实验很锻炼写实验报告的能力。