4.5 疑难解答和上机题
4.5.1 疑难解答
1. 输出数据时,使用格式%u与%d有什么不同?
解答:当要输出的数据是正数时,两者没有区别,这是因为正数的补码与原码相同,并且最高位符号位为0。当要输出的数据是负数时,两者将产生较大变化,因为负数的补码最高位为1。因此,使用无符号格式%u输出时,最高位也作为数据位输出,但使用%d输出时,最高位作为符号位输出。例如,定义变量a=-1,则变量a在内存中存储的数据为:
[-1]补码=11111111111111111111111111111111。因此,使用%u格式输出-1将得到32位无符号整型值为:4294967295。而使用%d格式输出为-1。
因此,为了避免出现错误结果,大家编写程序时一定要注意使用正确的输出格式。
2. 第2章曾介绍,int型和char型可以等价进行算术运算,那么使用%c格式输出int型数据,能得到什么结果呢?
解答:由于%c格式仅输出一个字节的内存数据,因此,当要输出的int型数据为小于255的正数时,使用%c格式可以将该数据转换为ASCII码值对应的字符输出,但前提是该字符为可显示字符。但当要输出的数据不在上述范围内时,首先应该将该数据转换成二进制补码形式,然后取低8位,最后转换为ASCII码值对应的字符并输出。例如,int型变量a=100,则使用%c格式输出a,系统将其低位字节的值转换为ASCII码值对应的字符并输出。100在内存中的存储格式为:
[100]补码=00000000000000000000000001100100
低位字节为01100100,值为100,与其对应的字符为:d。
3. 使用%f格式输出int型数据,会得到正确结果吗?
解答:int型数据在内存中占4个字节,而以%f格式输出时,系统将按照浮点数存储格式读取数据,关于浮点数的存储请参阅2.4.4节。因此,一般情况下,使用%f格式输出int型数据将得不到正确结果。例如,语句printf("%f", 100);输出的数值为:0.000000,这是因为整型值100以补码形式存储,请参考题2中的解答,而%f以浮点格式读取数据,精确到小数点后7位,因此读取后不能将其正确转为整型值,因此输出0.000000。
4. 怎样提高输出数据的精度?
解答:可以使用%f格式输出数据,%f包含两种类型的输出,一种是float型,一种是double型,后者的精度更高。因此,使用%f格式输出时,应使用强制类型转换将被输出的数据强制转换为double型,以提高数据输出精度,同时避免输出时得到错误的结果。例如,题3中,可以修改语句为:
printf("%f",(double)100);
5. 能不能使用%m.0f格式输出数据?
解答:可以的。这样的格式就是要输出数据的整数部分,但与%d格式不同的是,%d格式仅输出整数部分,小数点后的数据将被丢弃;而%m.0f格式输出时,在隐藏小数部分的同时,将小数部分四舍五入,以尽量提高输出结果的精度。
6. 输入函数scanf时,忘记取变量地址符&,程序如何运行?
解答:程序编译时一般不会报错,也没有警告信息,但程序运行时将出现崩溃性错误。例如:
int a=0;
scanf("%d", a);
程序段运行时输入数值10,按回车键,则程序将出现崩溃,弹出如图4-3所示的对话框。
图4-3 输入函数未取变量地址错误对话框
7. 输入函数scanf中,若要输入%,应如何操作呢?
解答:由于%是特殊控制字符,因此需要输入两个%来控制%的输入。例如,要想输入%99,则应该使用语句:
scanf("%%%d", &a);
输入方式为:%99,然后键入回车键即可。
8. 若输入浮点数给整型变量,变量的值将会是多少?
解答:当scanf函数中使用%d格式时,输入浮点数据后,系统将仅截取整数部分给要赋值的变量。例如:
int a=0;
scanf("%d", &a);
printf("%d\n");
当输入12.8并键入回车键时,输出值为:12。
9. 对于getchar函数,会不会将回车符作为字符输入呢?
解答:会的,所有的键盘符都可以作为字符输入给getchar函数,若键入回车符,系统将其默认为换行。例如:
char c; c=getchar(); printf("OK%cOk\n", c);
上述程序段运行后直接输入回车符,则输出为:
OK
OK
10. 可以使用getchar函数输入的字符进行算术运算吗?
char c; c=getchar(); printf("%c\n", c+32);
若键盘输入A,则输出结果为什么?
解答:可以。getchar函数输入后,将以ASCII码形式存放到内存中,读取时同样也是读取ASCII码值,然后作运算和处理。因此,getchar函数获取的字符与scanf没有本质区别,都可以参与算术运算。例如:
char c; c=getchar(); printf("%c\n", c+32);
上述程序段执行时,当键盘输入A,并按回车键后,c的值变为字符'A',同时其十进制值为65,printf函数中要输出ASCII码表中A向后第32个字符,即为a。因此程序输出为:a。
4.5.2 上机题
1. 使用scanf函数接收键盘输入的一个int型数据,使用printf函数以%f格式输出该数据,试编写程序实现上述功能。(提示:输出数据时可以使用强制类型转换)
2. 已知圆半径r为小于10的数,试编写程序,由键盘输入半径r的值,计算圆的面积和半径。圆周率pi = 3.1415,结果打印到屏幕上,取小数点后2位输出。
3. 使用%u格式无法正确输出正数的数值,但%u可以验证计算机填满某字节时对应的十进制数。试编写程序,输出4字节能表示的最大值,并以十进制数形式输出。(提示:4字节最大值的十六进制数表示为0xffffffff)。
4. 数据在计算机中以补码形式存储,而%c格式仅输出数值低字节的字符表示,试编写程序,分别使用%x和%c输出数据-100,并将结果打印到屏幕上。
5. %x用于输入和输出十六进制数,试编写程序,使用scanf函数以%x格式输入数值-1,然后使用printf函数分别以%x、%d和%u格式输出所输入的数据,将结果打印到屏幕上,并分析输出数据的含义。
6. 特殊符号%的输出应该使用两个%重复字符以区别该特殊字符的含义。试编写程序,打印公式字符串:a%b = a/b…c = d…c。其中,a和b为整型数据,且b不为0,通过键盘输入a和b,c和d由运算得到。
7. 试编写程序,使用getchar函数接收键盘输入的字母a和A,通过putchar函数输出这两个字母,并以%d格式输出两个字符的差。
8. 梯形的面积计算公式为S=(hw+lw)*h/2,其中hw表示上底长度,lw表示下底长度,h表示高。试编写程序,使用printf函数输入梯形的上底hw、下底lw和高h,计算梯形的面积 S,并将结果打印到屏幕上,精确到小数点后2位。(提示:除法计算时注意精度变化,可以使用强制类型转换实现)
9. 某班共63名学生,某次考试数学共x名学生考试及格。试编写程序,计算该班数学考试的及格率,使用百分数(%格式)表示,x由键盘输入,结果精确到小数点后2位。(提示:注意除法的计算和%的输出)
10. 试编写程序,实现对键盘输入信息的判断,当键盘输入字母h时,打印输出字符串"Hello, Your programme is right! "。