新编C语言程序设计教程练习二参考答案.docx
- 文档编号:24499791
- 上传时间:2023-05-28
- 格式:DOCX
- 页数:16
- 大小:22.44KB
新编C语言程序设计教程练习二参考答案.docx
《新编C语言程序设计教程练习二参考答案.docx》由会员分享,可在线阅读,更多相关《新编C语言程序设计教程练习二参考答案.docx(16页珍藏版)》请在冰豆网上搜索。
新编C语言程序设计教程练习二参考答案
练习二
2.1用计算机处理信息时为什么需要对信息进行数字化编码?
答:
现代计算机采用二进制形式表示数据和指令,计算机内部处理的所有数据都是经过数字化编码的二进制数据,数值、文字、图形等信息只有编码成二进制形式才能由计算机进行处理。
2.2编码数值型数据时需考虑哪三个方面的问题?
答:
1.编码的长度
2.正负号的编码
3.小数点的编码
2.3求码长1个字节的原码、反码和补码形式的定点整数分别能编码整数的范围与个数。
答:
原码:
11111111-01111111-127~127共255数
反码:
10000000–01111111-127~127共255数
补码:
10000000–01111111-128~127共256数
2.4求下列数的补码(码长1个字节)。
65-1123-123-128
答:
65:
01000001
-1:
原码10000001反码11111110补码11111111
123:
01111011
-123:
原码11111011反码10000100补码10000101
-128:
原码不能用1字节表示反码同样补码10000000
2.5从负数的反码加1得补码的过程说明补码的符号位可以看作是特殊的数值位的理由。
(提示:
以码长1个字节为例,用127减去负数原码的数值位就得到了负数的反码)
答:
以-123为例
原码11111011反码10000100补码10000101
01111111127
-11111011-123
100001004+1=510000101:
-128+5=-123
2.6求码长分别为2个和4个字节时第4题中几个数的补码,并分析码长变化时补码是如何变化的。
65-1123-123-128
答:
65:
0000000001000001
-1:
原码1000000000000001
反码1111111111111110
补码1111111111111111
123:
0000000001111011
-123:
原码1000000001111011
反码1111111110000100
补码1111111110000101
-128:
原码1000000010000000
反码1111111101111111
补码1111111110000000
65:
00000000000000000000000001000001
-1:
原码10000000000000000000000000000001
反码11111111111111111111111111111110
补码11111111111111111111111111111111
123:
00000000000000000000000001111011
-123:
原码10000000000000000000000001111011
反码11111111111111111111111110000100
补码11111111111111111111111110000101
-128:
原码10000000000000000000000010000000
反码11111111111111111111111101111111
补码11111111111111111111111110000000
变化规律为:
正数前面补0,负数前面补1。
2.7用实例证明码长2个字节的补码形式整数的取值范围也构成一个环。
分析下面程序的输出结果。
答:
#include
voidmain()
{
shorti=32767,j=-32768;
printf("%hd+1=%hd\n",i,i+1);
printf("%hd-1=%hd\n",j,j-1);
}
当变量i和j的值为127和-128时,程序的运行结果又怎样?
答:
输出结果为:
32767+1=-32768
-32768-1=32767
当变量i和j的值为127和-128时,程序的运行结果为:
127+1=128
-128-1=-129
因为short型变量的取值范围为-32768到32767,所以值128和-129不会溢出。
2.8升序排列下面的整型字面量。
0xac1690253
0xac的值为172,0253的值为171。
升序排列为168,0253,0xac。
2.9编程输出下面整型字面量的十进制、八进制、十六进制形式。
(用int型变量存储数据,但分别用〝%h?
〞与〝%?
〞两种格式输出,并注意两者的区别)。
96,0100347,0xffff
答:
从输出可以看出:
变量i、j、k的存储状态分别为:
00000000000000000000000001100000
00000000000000001000000011100111
00000000000000001111111111111111
2.10在%和格式字符d(o,x)之间也可以插入一个正整数(m),指定输出数据所占的最小宽度。
分析下面程序的输出。
#include
voidmain()
{
shorti=12,j=34;
printf("%d%d\n",i,j);
printf("%3d%4d\n",i,j);
}
在%与m之间,还可以插入一个“-”号,表示左对齐输出。
在上面程序最后加一条语句printf(〝%-3d%-4d\n〞,i,j);再分析比较输出结果。
答:
printf("%d%d\n",i,j);会连续输出变量ij的值,输出结果为1234。
printf("%3d%4d\n",i,j);中%3d意味变量i的值至少占3列右对齐,即空格12。
%4d%3d意味变量j的值至少占4列右对齐,即空格空格34。
输出结果为空格12空格空格34。
rintf(〝%-3d%-4d\n〞,i,j);中-要求左对齐,%-3d的输出为12空格。
输出结果为12空格34空格空格。
2.11有一内存空间的存储状态为
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
,该内存空间的值是多少?
分析下面程序的运行结果。
#include
voidmain()
{
shorti=-1;
printf("%hd\n%hu\n",i,i);
}
printf函数中的格式字符必须与对应的变量类型一致吗?
如果可以不一致,格式字符可以是任意的吗?
在上面程序的最后加一条语句printf("%f\n〞,i);,再查看输出结果。
答:
解码方式不同,内存空间中数据有不同的值。
程序中变量i所标示的内存空间的状态即如图所示。
当以%hd格式解码时,它的值为-1,当以%hu格式解码时,它的值为65535。
printf函数中的格式字符不必与对应的变量类型一致,对应的变量仅表示要解码的数据位于何处。
如何解码由printf函数中的格式字符决定,所谓的printf函数是“我的地盘我作主”。
但是,格式字符也不可以是任意的。
以上面为例,补码形式的16个1,可以按无符号格式%hu解码,也可按有符号格式%hd解码,但不能以浮点型解码,无法把16个1按浮点型解码,因此printf("%f\n〞,i);的输出结果就出错。
2.12短整型(short)变量可以用无符号短整型格式(%hu)输出。
如上题中-1的输出值为65535,-2和-3的输出值是多少呢?
验证你的分析,并总结一下短整型变量i为负值但用无符号短整型格式(%hu)输出时的输出规律。
答:
-1:
65535
-2:
65534
-3:
65533
通过观察,规律为:
变量i为负值但用无符号短整型格式(%hu)输出时的输出为65536+i。
理论证明:
变量i为负,则符号位为1,按有符号数格式解码时这个1表示-32768;按无符号数格式解码时,这个1表示32768,两者相差65536。
原来:
-32768+x=i(x=32768+i)
现在值为32768+x,即32768+32768+i=65536+i。
2.13用二进制形式的科学计数法表示下面的数(尾数为纯小数)。
65535,125.125,125125125.125E3,123.456,123456
初始化浮点数变量时一定会出现误差吗?
什么情况下才会出现误差?
用写成浮点数字面量形式(123.0)的短整型整数(123)来初始化单精度浮点数变量时会出现误差吗?
答:
65535=111111*********1=0.111111*********1E10000
125.125=1111101.001=0.1111101001e111
125125125.125E3=125125125125=1110100100010000010011110010000000101=0.1110100100010000010011110010000000101e100101
123.456=1111011.0111010010111100011010101=0.111101*********10111100011010101e111
123456=11110001001000000=0.11110001001000000e10001
初始化浮点数变量时不一定会出现误差。
只有十进制数的小数部分不能精确转化(如123.456)或虽然可以精确转化但浮点数没有那么大的存储空间存储(如125125125.125E3可以精确转化但转化后要37位才能准确存储其尾数,将其存入float型变量时就肯定有误差了)。
短整型整数的取值范围为-32768到32767,且都能精确转化为二进制,当用指数形式表示时尾数最多要16位的存储空间,而float型的尾数有23位,可以存下,因此用写成浮点数字面量形式(123.0)的短整型整数(123)来初始化单精度浮点数变量时一定不会出现误差。
2.14指出下面数据中不合法的浮点数字面量。
233.0,791E+2,2.e3,2e3,12e2.0,3.,0.791E-2,.8
答:
以.8为例,可以用下面的程序进制测试,能编译通过没有语法错误的就是合法的。
#include
voidmain()
{
floatf=.8;
printf("%e\n",f);
}
不合法的有:
12e2.0
有同学用程序
#include
voidmain()
{
floatf;
scanf("%f",&f);
printf("%e\n",f);
}
测试时输入12e2.0,程序运行正确,就认为12e2.0也为合法的浮点型字面量。
出现这种情况与scanf函数有关,当它遇到非法字符时自动停止转换,这个例子中,scanf函数遇到小数点后就停止了转换,把12e2赋值给了变量f。
输入12e2.3时程序的输出依然为1.200000e+003。
2.15程序
#include
voidmain()
{
floata=702.1;
printf("%e\n",a);
}
的输出为7.021000e+002,有同学觉得此时不存在误差,你的看法呢?
用格式字符f再次输出变量a的值。
答案:
存在误差,此时小数点后有6位,在精度范围之内,好像没有误差。
格式字符f再次输出变量a的值为702.099976,误差很明显。
2.163.11+3.12等于6.23吗?
查看下面程序的输出。
#include
voidmain()
{
floatfa=3.11,fb=3.12;
printf("%.2f\n",fa+fb);
printf("%.2f\n",6.23);
}
把%.2f替换为〝%.8f〞和〝%.18f〞后,再次查看输出结果。
查看下面输出语句的输出。
printf("(3.11)%.18f+(3.12)%.18f=%.18f\n〞,fa,fb,fa+fb);
printf("(6.23)%.18f\n〞,6.23);
答案:
输出为:
6.23
6.23
用〝%.8f〞后的输出结果为:
6.22999978
6.23000000
用〝%.18f〞后的输出结果为:
6.229999780654907200
6.230000000000000400
语句printf("(3.11)%.18f+(3.12)%.18f=%.18f\n〞,fa,fb,fa+fb);和printf("(6.23)%.18f\n〞,6.23);的输出结果为:
(3.11)3.109999895095825200+(3.12)3.119999885559082000=6.229999780654907200
(6.23)6.230000000000000400
综上所述,不等于。
2.171/3*3=?
1.0/3.0*3.0=?
分析下面程序的输出结果。
#include
voidmain()
{
inti=1/3;
floatf=1.0/3.0;
printf("1/3=%d\t1/3*3=%d\n",i,i*3);
printf("1.0/3.0=%f\t1.0/3.0*3.0=%.10f\n",f,f*3.0);
printf("1.0/3.0*3.0=%.10f\n",1.0/3.0*3.0);
}
答案:
1/3*3=0*3=0
1.0/3.0*3.0=1
计算机在计算1.0/3.0*3.0时有优化,使得结果为1。
2.18根据double型的精度和取值范围,估算double型的尾数和阶码各占多少位。
答案:
10-16<2-x<10-15可得16/㏒2>x>15/㏒2,即53≥x≥50。
10308=2x可得x=308/㏒2≈1023,码长11位时,取值范围为-1024至1023。
故double型的尾数占53位和阶码占11位,共64位,8个字节。
2.19sizeof是一个操作符,可以返回一个变量或者数据类型所占的内存字节数。
分析下面程序的运行结果。
#include
voidmain()
{
inti=5;
printf("int(Bytes):
%d\n",sizeofi);
printf("longdouble(Bytes):
%d\n",sizeof(long
double));
}
答案:
可见VC6.0中,int型占4个字节,longdouble型占8个字节。
0
0
10
11
1
0
01
1
2.20有一内存单元的存元储状态为,该内存单元存储的是什么数据?
分析下面程序的运行结果。
#include
voidmain()
{
charca='9',cb=57;
printf("%3d%3c\n",ca,ca);
printf("%3d%3c\n",cb,cb);
}
从程序的可读性角度分析,哪种字符变量的初始化方法较好?
答案:
内存单元存储的是什么数据与其编码格式相关,当认为其为整数的补码时,存储是整数57;当认为其为字符的ASCII型,存储是字符9。
从程序的运行结果可知,变量ca和cb的存储状态完全一样。
从程序的可读性角度分析,应使用charca='9'的方式初始化字符变量。
2.21分析下面程序的输出,总结转义序列\t、\b和\r的作用。
#include
voidmain()
{
printf("%d\t%d\t%d\n",23,23,23);
printf("%d\t%d\t%d\n",232323,123456789,23);
printf("%d\b%d\n",23,56);
printf("%d\r%d\n",123,56);
}
答案:
输出\t与按下Tab键的效果相同。
按下Tab键时,光标会向右移动,但它不是移动1个字符或者是固定的几个字符,它会移动到下一个8×n+1位置(n为自然数)。
\b退格,将输出位置移到前一列,故printf("%d\b%d\n",23,56);的输出为256(3被5“覆盖”了)。
\r回车,将输出位置移到本行开头,故printf("%d\r%d\n",123,56);的输出为563(12被56“覆盖”了)。
2.22用户输入zzj回车时,分析下面程序的运行情况,并与例2-11比较。
#include
voidmain()
{
charca,cb;
ca=getchar();
cb=getchar();
putchar(ca);
putchar(cb);
}
语句cb=getchar();中的getchar函数让用户输入了吗?
用户“多余”的输入会“丢失”吗?
scanf函数有类似的现象吗?
编程验证。
答案:
程序的输出为:
可见,语句cb=getchar();中的getchar函数没有让用户输入,因此,用户“多余”的输入不会“丢失”。
可见,scanf函数也有类似的现象。
2.23分析下面程序的运行情况。
#include
voidmain()
{
intx,y;
charca,cb;
scanf("%d%d",&x,&y);
ca=getchar();
cb=getchar();
printf("%3d%3d\n",x,y);
printf("%3d%3c\n",ca,cb);
}
输入为:
523回车
6回车
输出为:
523
106
注意:
用户的输入会放置在“输入缓冲区”中,scanf函数和getchar函数共用一个输入缓冲区。
程序开始运行时,输入缓冲区为空。
输入函数执行时会先访问输入缓冲区,有数据时取走数据并返回,没有数据时等待用户输入数据。
只有输入函数取走了数据,相关的用户输入才会从缓冲区中移出。
10是哪个字符的ASCII码?
用户第一次输入结束后,“输入缓冲区”中依次为5空格23和回车符,scanf函数获得用户输入时,先“取走”了5并赋值给变量x,又“取走”并忽略了空格,最后“取走”了23并赋值给变量y,当scanf函数返回时“输入缓冲区”中还剩有一个换行符。
答案:
因此当语句ca=getchar();执行时,getchar会访问“输入缓冲区”并把剩下的换行符返回给变量ca。
当语句cb=getchar();执行时,getchar也会访问“输入缓冲区”,发现其中为空后请求用户输入数据。
用户输入6↙后,getchar返回并把字符6赋值给变量cb。
因此printf("%3d%3c\n",ca,cb);的输出为“106”,其中10为字符变量ca存储字符的(换行符)ASCII码。
2.24字符变量可以进行加减运算吗?
分析下面程序的运行结果。
#include
voidmain()
{
charca='c';
shorti='H';
putchar(ca-32);
putchar(i);
putchar('i'-('a'-'A'));
putchar(72);
printf("A!
\n加油!
\n");
}
答案:
可见,字符变量可以进行加减运算。
程序中通过加减运算,把小写字符变成了大写字符。
2.25字符型字面量可以进行乘除运算吗?
'A'*3=?
请编程验证。
C语言中允许在char类型前加上修饰符signed(有符号)和unsigned(无符号)。
signedchar的取值范围是-128~127,而unsignedchar的取值范围是0~255。
在VC6.0中,char类型的取值范围是多少呢?
编程验证。
你同意C语言中char类型就是码长为1个字节的整型这个观点吗?
答案:
可见,字符型字面量可以进行乘除运算,不过字符型的乘除运算通常无意义。
验证VC6中char型变量取值范围的程序如下:
验证程序先把-11赋值给变量ca,如果ca为“无符号”的,则它在计算时的值为正数。
如果ca大于0,则它除以-3的商为负值,则余数为ca-商×-3,结果大于0。
如果ca小于0,则它除以-3的商为正值,则余数为ca-商×-3,结果小于0。
程序的输出为-2,显然ca为负值。
VC6中char型变量取值范围为-128-127,为“有符号”数。
特别注意:
不能用类似printf(”%d\n”,ca);的语句判断变量ca的正负。
可以把C语言中char类型看成码长为1个字节的整型。
2.26阶乘函数的功能就是求一个整数的阶乘,输入一个整数,输出该整数的阶乘,但是整数的阶乘通常较大。
用short作函数返回值类型时,阶乘函数最大能正确输出哪个整数的阶乘?
分别unsignedshort、long、unsignedlong、float和double作函数返回值类型时,情况又怎样呢?
答案:
short型最大取值为32767,7!
=5040,8!
=40320,它只能输出7的阶乘。
unsignedshort型最大取值为65535,9!
=362880,它只能输出8的阶乘。
long型最大取值为21亿多,12!
=479001600,13!
=6227020800,它只能输出12的阶乘。
unsignedlong型最大取值为42亿多,12!
=479001600,13!
=6227020800,它只能输出12的阶乘。
float型的最大取值虽然很大,但是精度只能保证6-7位,由程序的输出可知,14!
=87178291200已经出错,它只能输出13的阶乘。
double型的精度只能保证15-16位,由程序的输出可知,22!
=
1124000727777607680000,23!
=25852016738884976640000已经出错,它只能输出22的阶乘。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 新编 语言程序设计 教程 练习 参考答案