七、编程题1.求斐波那契数列的前30项。该数列的变化规律是:前两项都是1,从第三项开始的每一项等于其前面两项之和。2.从键盘输人一个正整数,求其总位数。3.从键盘输入一批以@作为结束标记的字符,分别统计其中字母、数字及其他字符的个数4.猴子吃桃问题。某一天猴子摘了若干个桃子,当即吃掉一半,仍不过瘾,又多吃了一个。第二天再将剩下的桃子吃掉一半又多吃了一个。以后每天都是吃掉前一天剩下的一半零一个。到了第十天想再吃时,发现只剩下一个桃子了。求出第一天总共摘了多少个桃子。5.已知数列1/2,2/3,3/5,5/8,…,求其前10000项之和。6.利用公式e=1++六+六+计算自然常数e的近似值,直至某一项的值小于10-151!2!3!时停止累加。7.求a+aa+aaa+aaaa+(如2+22+222+2222+22222)的前n项之和。a),要8.用迭代法求算术平方根,已知求α的算术平方根的迭代公式为x=o20Xo求误差小于10-169.用双重循环打印如下图形,限定每条语句只能输出一个字符。*学出所************************第三单元习题参考答案及解析一、判断题1.错误。第解析:若循环条件一开始为假,则循环体不执行(while循环或for循环)或至少执行5-次(do-while循环)。对于for循环,由于可以在其表达式3中改变循环变量的值,故即章使循环体为空语句,循环也可以正常退出。例如,循环for(i=1;i<=10;i++);并不是死循环。对于while循环和do-while循环,由于可以在其条件表达式中改变循环变量的值,故即使循循环体为空语句,循环也可以正常退出。例如,循环i=l;while(i++<=10);也不是死循环。环所以,循环体为空语句的循环不一定是死循环。结2.正确。构程解析:C语言的语法规定:循环体只能是语法意义上的单条语句。若循环体有多条语库句,则必须用花括号括起来,从而构成一条复合语句。设3.正确。计49
解析:前自增与后自增的基本功能是使变量的值加1。当其单独作为一个表达式时,二者是没有区别的;只有作为另一个表达式的一部分时,二者才有区别。因此,表达式计+与++i是没有区别的,从而语句i++;与语句++i;的功能是完全相同的。4.正确。解析:从功能上来说,for循环与while循环是完全等价的,只是表现形式不同而已。for循环可以看作由while循环变形而来,也就是将给循环变量赋初值的语句和递变循环变量值的语句合并到for语句的括号之中。5.错误。解析:在传统C语言中,前自增运算与后自增运算的优先级是相同的。但是,从C89标准开始,已将前自增运算与后自增运算的优先级分开,且后自增运算的优先级高于前自增运算。6.错误。解析:C语言语法规定,循环条件通常为关系表达式或逻辑表达式,也可以是任意的结果类型为整型、实型、字符型、枚举型和指针型的表达式。而且,只要表达式的值非0,就看作真;只要表达式的值为0,就看作假。7.正确。解析:当在循环体中执行break语句时,将会立即跳出本层的循环体,从而提前结束循环。因而,相当于break语句改变了循环的条件,从而能够改变循环的次数。当循环体中执行continue语句时,其功能是跳过循环体中continue之后的那一部分循环体,而继续进行下一次循环。可见,continue语句只是改变了循环体的范围,而并未改变循环的条件,因此不会改变循环的次数。二、选择题1. BC解析:在程序A中,将while语句头与循环体同时括起来,此时的循环体是紧跟在while语句头之后的printf语句,而并不包括i++;语句。因而,在循环过程中,变量i的值将始终保持不变,从而循环条件始终为真,是一个死循环。在程序B中,for循环的循环体是行未的分号,即空语句,而不是其后的printf语句。不过,该循环将在循环10次(i变为10)之后结束,因而不是一个死循环。在程序C中,循环变量i的初值为0,循环条件是i>=0,循环变量递变表达式为i++。似乎循环条件始终为真,其实不然。这是因为变量i是有符号短整型变量,当i通过不断加c1而变为最大值32767时,若再加1,将会因为溢出而变为-32768,从而导致循环条件为假语而退出循环。言在程序D中,循环变量i的初值为0,循环条件是>=0,循环变量递变表达式为i++。程因为变量i是无符号短整型变量,当i通过不断加1而变为最大值65535时,若再加1,将序会因为溢出而变为0,仍然满足循环条件而继续循环,导致循环条件始终为真,所以是一设个死循环。计训2. B练解析:在程序A中,for语句的表达式3为i+2,实际上不会改变循环变量i的值,因教为没有进行赋值。因此,在循环过程中i的值始终不变,循环条件<10始终为真,所以是程50
一个死循环。在程序B中,如果没有if-continue部分,将会循环输出1oo次。循环体中if语句的条件为i%2,等价于i%2!=0。因此,当i的值是奇数时,执行continue语句,跳过之后的printf语句。故程序将输出0~99的所有偶数,然后退出循环。在程序C中,for语句的循环条件缺省,此时视为循环条件始终为真。循环体中if语句的条件为i%2,等价于i%2!=0。因此,当i的值是奇数时,执行continue语句,跳过之后的printf语句,故程序将输出所有的偶数。但continue语句并不能使程序退出循环,因此这仍是一个死循环。在程序D中,循环体中if语句的条件为!(i%2),等价于i%2一0。因此,当i的值是偶数时,执行continue语句。表面上看,当i的值是奇数时,将会执行i++;语句。但是变量i的初值为o,if条件一开始即为真,导致执行continue语句而返回到while(i<1oo),并再次执行循环体的if语句。在此过程中,i计+语句没有机会得到执行,使得变量i的值始终不变,循环条件始终为真。因此,这也是一个死循环。3.A解析:在程序A中,虽然循环次数和循环变量的取值都正确,但是循环体语句p=i*(i+1)不具有累乘的功能,因为在累积运算表达式中,存放结果的变量名必须同时出现在赋值运算符的两侧。因此,变量p最后的值为10*(10+1)=110,并不是10!的值。在程序B中,循环次数和循环变量的取值都正确,累积变量的初值和累积运算表达式也都正确,故能求出10!的值。在程序C中,累积变量p的初值为1,循环变量i从10递变到2,并通过p=p*i;将其每个取值累乘到变量p中,故也能求出10!的值。在程序D中,for循环共循环5次,变量i与j的取值分别是1和10、2和9、3和8、4和7、5和6。通过执行循环体语句p=p*i*j;也可以将1~10累乘到变量p中,故也能求出10!的值。4. C解析:在本程序中,外循环变量i依次取1,5,9,13,共循环4次;内循环变量依次取3,7,11,15,19,共循环5次。故内循环的循环体语句m++;共执行4×5=20次,m最后的值为20。5. B解析:变量x的初值为3,当第1次执行循环体时,表达式x-=2的值(等同于变量x的值)为1,故输出1;然后执行while(!(--x));,x的值变为0,--x的值也为0,!(--x)第为1,循环条件为真从而继续循环。当第2次执行循环体时,表达式x--2的值(等同于变5章量x的值)为-2,故输出-2;然后执行while(!(--x)),x的值变为-3,--x的值也为-3,!(--x)为0,循环条件变为假从而退出循环。循6.A环解析:在for循环中,变量i取值为1到100。如果+1能被2整除、计+2能被3整除、结计3能被7整除,则输出i+3的值。假设最终输出的值为x,则x能被7整除、x-1能被3构整除、x-2能被2整除。对比给定的4组结果,可以发现只有选项A符合要求。程库7. B设解析:在该程序中,外循环变量i分别取值3,2,1,内循环变量分别取值1,2。故计51
内循环的循环体printf("%d",i+j);共执行6次。第1次,i=3,j-1,itj=4;第2次,i=3,j-2,ij-5;第3次,i=2,j-1,itj=3;第4次,i=-2,j-2,ij=4;第5次,i=1,j=1,ij-2;第6次,i=l,j=2,i+j=3。由于换行语句printf("n");位于内循环体之外、外循环体之内,故将进行3次换行。8. D解析:在该程序中,for循环共循环6次,循环变量i取值为0~5。循环体中if条件为i%2,等价于i%2!=0,即当i为奇数时,if条件为真执行if子句;当i为偶数时,if条件为假执行else子句。因此,当i取0时,输出c+i=A+0-'A;当i取1时,输出b+i-a'+l=b':以此类推。三、填空题1.整型实型字符型非00解析:循环的条件通常为关系表达式或逻辑表达式,也可以是任意的结果类型为整型实型、字符型、枚举型和指针型的表达式。而且,只要表达式的值非0,就看作真:只要表达式的值为0,就看作假。2.-6、7解析:当表达式b=-a++求值时,由于后自增的优先级高于取负,故首先求得a++的值为6,然后取负为-6并赋给变量b,故b的值为-6。由于在对a++求值时,a的值自增加1,故a的值为7。3.25解析:按照逗号表达式的求值步骤,依次执行a=3,a++与++a,此时a的值为5;再执行a+3,a的值不变,因为并没有对变量a进行赋值;因而最后求得a*5的值为25。可见,在逗号表达式中,除了最后一个表达式之外,如果在前面的表达式中没有对变量进行赋值,那么这个表达式实际上不起作用。4. 7解析:表达式b-=a+3等价于b=b-(a+3)而不是b=b-a+3,即应将复合赋值运算符的右侧部分括起来作为一个整体参与运算。5.真解析:在for语句中,循环条件缺省,也就是没有循环条件,相当于循环条件永远满足,即永远为真。6. 1解析:由于do-while循环先执行一次循环体,再判断循环条件是真是假,故其循环体c语至少执行一次。言四、读程序写结果程库1.运行结果:设10计解析:该程序看起来似乎应该输出0~9这十个数,其实不然。这是因为在for(i=0;<10i++)之后有一个分号,这个分号会视为空语句,从而使得循环体是空语句。因此,练语句printf("%dn",i);只在循环结束之后执行1次,此时变量i的值为10。察程2.运行结果:52
0,01,12,2解析:有人认为该程序的运行结果应该包括变量i、i的所有取值的组合,即0,00, 10, 21, 01, 11,2其实不然。这是因为该程序中的for循环是单重循环,其循环条件i<2,j<3;是一个逗号表达式,实际上起作用的是j3(从左到右求值,并取最右一个表达式的值)。故第1次输出0,0,然后变量i、j的值分别自增;第2次输出1.1,然后变量i、i的值分别自增;第3次输出2,2,然后变量i、j的值分别自增。此时,变量i、i的值均为3,从而因循环条件为假而退出循环。若想输出变量i、的所有取值的组合,则应该采用如下的双重循环结构#include<stdio.h>int main(void)(int i,j;for(i=0;i<2;i++)for(j=0;j<3;j++)printf("sd,gdln",i,j);return O;3.运行结果:00,00,10,21,01,11,2*****第解析:在该程序中,双重循环部分用两层花括号括了起来,但是外层花括号实际上不5起作用。这是因为C语言的语法只要求将循环体用花括号括起来,而并不要求将for语句華的语句头也包括在内。因此,此处内循环的循环体是printf("%d.%d\n"i.i);这一条语句,而外循环的循环体是(for(j-0;j<3;j++)printf("%d,%d/n",ij);,语句printf("*****n");橋环则处于外循环体之外。明确了双重循环的边界,也就不难写出程序的运行结果结4.运行结果:构1程222序33333设4444444计53