1 实验二 C语言程序设计基础 2-1 编程(文件名为S2-1.C)。定义3个int变量x,y,z和一个实型变量average, 计算并输出3个整数的平均值average,即 average=(x+y+z)/3,其中x,y,z 的值可以通过变量的初始化赋值x=1,y=1,z=0,也可以通过赋值语句赋值。 观察运行结果。将x,y,z和average改为实型变量,再观察运行结果。理解 整除和不同类型数据进行混合运算的转化规律,对结果进行合理的解释。 〖指导〗 (1) 当把x,y,z定义为整型变量时,所做运算(x+y+z)/3是整除运算,根据 C语言的语法规定:整除结果是舍去小数部分,保留整数部分,而不做四舍五入。 因此,average=(x+y+z)/3是将取整的结果赋给average。 (2) 当定义x,y,z为整型,x=1,y=1,z=0时,average的值就为0。要想使average 的值为非0,除非将x+y+z的值或3转换为实型。可用如下方法之一进行转换: ① average=(x+y+z)/3.0; (把3改为3.0) ② average=(float)(x+y+z)/3; (把x+y+z的结果强制转换为实型) (3) 如果把x,y,z和average都定义为float型,结果就不再为0,而是等于 0.67。 通过该程序的编写,目的是进一步认识数据的类型,以及不同类型数据的混 合运算。 2-2 改写程序S2-1.C(文件名为S2-2.C),通过键盘用scanf()函数输入x,y,z的 值。要求输出结果的形式为average=…。 〖指导〗 在S2-1.C中,变量x,y,z的值是通过变量的初始化或赋值语句赋的值。用这 种方法编的程序不灵活,如果要改变x,y,z的值,就要修改程序。如果用scanf() 函数输入x,y,z的值,就不需要对程序做任何修改,只需在运行程序的过程中, 给x,y,z输入所需的值。 比较下面三个程序,模仿比较好的一种方法编写S2-2.C。 源程序S2-2-1.C #include <stdio.h> 2 main() { int x=1,y=1,sum; /* 定义变量 */ sum=x+y; /* 求和 */ printf ("sum=%d\n",sum); /* 输出 */ } 该程序只能求x=1与y=1的和,如果要求其他数据的和,必须修改程序中的 初始化,然后重新编译、连接并运行。 源程序S2-2-2.C #include <stdio.h> main() { int x,y,sum; /* 定义变量 */ scanf("%d%d",&x,&y); /* 输入 */ sum=x+y; /* 求和 */ printf ("sum=%d\n",sum); /* 输出 */ } 该程序可以求任意两个数的和,而不需要修改程序。当程序运行时,输入要 求和的数,程序就可输出结果。 源程序S2-2-3.C #include <stdio.h> main() { int x,y,sum; /* 定义变量 */ printf("\nEnter x y: "); /* 提示输入 */ scanf("%d%d",&x,&y); /* 输入 */ sum=x+y; /* 求和 */ printf ("sum=%d\n",sum); /* 输出 */ } 该程序与S2-2-2.C的区别是:在输入之前增加了屏幕提示,在运行程序时, 可按屏幕提示进行数据的输入。 运行上面每一个程序,真实感受一下它们的不同。 3 通过该程序的编写,目的是从一开始就采用较好的编程风格。 提示: 通过S2-2-1.C、S2-2-2.C、S2-2-3.C程序的编写,应该学会用良好的编程风 格编写程序。 (1) 编写程序时要考虑程序的通用性,需要变化的量尽量不要通过赋值的方 式给定(例如,S2-2-1.C中的x和y),而是通过输入的方式使变量得到当前所 需的值(例如,S2-2-2.C中对x和y的输入)。 (2) 从键盘输入数据时,最好先给出提示信息,提示要输入的数据(例如, S2-2-3.C中在输入x和y前用printf()函数输出的屏幕提示信息)。 2-3 运行程序S2-3.C,观察输出的结果,并对输出结果作出合理的解释。 源程序S2-3.C main() { float a1,a2; double b1,b2; a1=3141.59; a2=0.000001; b1=3141.59; b2=0.000001; printf("%f, %lf\n", a1+a2, b1+b2); } 〖指导〗 程序中的a1和b1、a2和b2的值分别相同,但程序中a1+a2和b1+b2的输 出结果却不会相同。这是因为float型数据和double型数据的精度不同,实型数 在计算机中是非精确表示的,用float型变量作两个位数很大的数的加法运算或 除法运算时,将得不到预期的结果,而用double型变量进行运算则可以得到较 准确的结果。 该程序的目的是进一步认识不同类型的数据,其精度是不相同的,编程时应 该根据要求定义变量的类型。 4 2-4 下面程序(S2-4.C)的输出结果是什么?对输出结果给予合理的解释。 源程序S2-4.C main() {char ch; int k; ch='a'; k=10; printf("%d, %x, %o, %c", ch, ch, ch, ch, k); printf ("k=%%d\n",k); } 〖指导〗 在C语言中,字符数据既可以用字符形式输出,也可以用整数形式输出。 字符a的ASCⅡ十进制代码为97,按十六进制形式输出为61,按八进制形式输 出则为141。本题中第一个printf函数调用中输出项k 为多余的,因此不予输出; 第二个printf函数调用语句中的格式说明中包含了两个连续的%字符,根据C语 言的规定,%%不再作为格式描述字符使用,而是处理成字符“%”的原样输出, 因此该句中的输出项k任然没有对应的格式描述符,也将不予输出。 该程序的目的是为了掌握变量按不同格式的输出,进一步认识格式描述符, printf函数中参数的正确使用。 2-5 写出程序(S2-5.C)的运行结果,并对输出结果给予合理的解释。 源程序S2-5.C #include <stdio.h> main() {float x; double y; x=213.82631; y=213.82631; printf ("%-4.2f, %-6.2e\n", x,y); } 〖指导〗 5 使用f格式描述符输出浮点数时的一般形式是%m.nf或%-m.nf,其中m指定 输出数据所占的总列数;n指定小数点后的位数,“-”是使输出数据左对齐,当输 出数据宽度大于m时,数据的整数部分将按照实际位数输出,在本例中由于输 出数据宽度大于m,因此%后面的“-”对输出格式无影响。使用e格式描述符输出 浮点数时的一般形式是%m.ne或%-m.ne,其中m、n、“-”的含义与f格式相同。 在不同的计算机中,对指数部分应占的宽度规定不同,而数值部分均按标准化指 数形式输出(即小数点前必须有而且仅有一位非零数字)。该题中y的实际宽度 为9,而格式说明中所给定的域宽为6,所以只能按标准化指数形式输出y的整 数部分,截去小数部分并四舍五入。 该程序的目的是为了进一步认识格式描述符。 2-6 下面程序(S2-6.C)的功能是从键盘上输入x=25,y=36.7,c=C,然后将输 入的内容输出到屏幕上。调试程序S2-6.C,修改有错误的语句行,并输出正 确的结果。 源程序S2-6.C #include <stdio.h> main() { int x; float y; char c; scanf("x=%d,y=%d,c=%c",x,y,c); printf("\nx=%d,y=%d,c=%c",x,y,c); getch(); } 〖指导〗 调试程序S2-6.C时要注意的问题有: (1) 函数scanf()的输入表列要求是变量地址的表列,否则在编译时会给出警 告错误: Possible use of xxx before definition (2) 函数scanf()的格式描述符要与输入表列中变量的类型一致。如果类型不 6 一致,将得不到正确的输入值。如果float型变量用%d格式输入,得到的是0; int型变量用%f格式输入,运行时会给出错误信息: scanf: floating point formats not linked Abnormal program termination (3) 如果函数scanf()的格式描述符中有按原样输入的字符,输入数据时一定 要按格式输入这些字符。 (4) 函数printf()的格式描述符要与输出表列中变量的类型一致。否则得不到 正确的输入结果。如果float型变量用%d格式输出,得到的是0;int型变量用 %f格式输出,运行时会给出错误信息: printf: floating point formats not linked Abnormal program termination 2-7 编程(S2-7.C)。执行下列语句后,a,b,c,d,e的值分别等于多少?为什么? int a,b,c,w=1,x=2,y=3,z=4,d=5,e=6; a=b=c=1; ++a||++b&&++c; (d=w>x)&&(e=y>z); 〖指导〗 在逻辑表达式的计算中要注意: (1) 对于++a||++b&&++c运算,若++a为真,后面的运算就不再进行。 (2) 对于++a&&++b||++c运算,若++a为真,继续计算++b,若++b为真,就 不再计算++c;若++b为假,则继续计算++c。 (3) 逻辑运算或关系运算的结果是一个逻辑值,即0或1。 2-8 假设有unsigned int a=3,b=10; char c=9, d=020; 计算a<<2|b>>1和~c&d<<1的结果,并编程(S2-8.C)验证。 〖指导〗 (1) 进行位运算时,先将要运算的数据转换为二进制。 (2) 对于a<<2|b>>1,移位运算优先于按位或运算。 (3) 对于~c&d<<1,左移运算优先于按位与运算,求反运算符优先级最高。