admin 管理员组文章数量: 887053
2024年1月4日发(作者:requests的意思)
《全国计算机等级考试二级教程——C语言程序设计》
课后题及参考答案
第一章 程序设计基本概念
1.1 在TRUBO C环境中用RUN命令运行一个C程序时,所运行的程序的后缀是______。
答案:.exe
1.2 C语言源程序文件的后缀是_____,经过编译后,生成文件的后缀是_____,经过连接后,生成文件的后缀是_____。
答案:.c .obj .exe
1.3 结构化程序由_____、_____、_____三种基本结构组成。
答案:顺序、选择、循环
第二章 C程序设计的初步知识
一、选择题
2.1 以下选项中正确的整型常量是
A)12. B)-20 C)1,000 D)4 5 6
答案:B
2.2 以下选项中正确的实型常量是
A)0 B)3. 1415 C)0.329×10(2)(10的2次方) D).871
答案:D
2.3 以下选项中不正确的实型常量是
A)2.607E-1 B)0.8103e 2 C)-77.77 D)456e-2
答案:B
2.4 以下选项中不合法的用户标识符是
A)abc.c B)file C)Main D)PRINTF
答案:A
2.5 以下选项中不合法的用户标识符是
A)_123 B)printf C)A$ D)Dim
答案:C
2.6 C语言中运算对象必需是整型的运算符是
A)% B)/ C)! D)**
答案:A
2.7 可在C程序中用作用户标识符的一组标识符是
A)void define WORD
B)as_b3 _123 If
C)For -abc case
D)2c DO SIG
答案:B
2.8 若变量已正确定义并赋值,符合C语言语法的表达式是
A)a=a+7; B)a=7+b+c,a++ C)int(12.3%4) D)a=a+7=c+b
答案:B
2.9 以下叙述中正确的是
A)a是实型变量,C允许进行以下赋值a=10,因此可以这样说:实型变量中允许存放整型值。
B)在赋值表达式中,赋值号右边既可以是变量也可以是任意表达式。
C)执行表达式a=b后,在内存中a和b存储单元中的原有值都将被改变,a的值已由原值改变为b的值,b的值由原值变为0。
D)已有a=3,b=5。当执行了表达式a=b,b=a之后,已使a中的值为5,b中的值为3。
答案:B
2.10 以下叙述中正确的是
A)在C程序中无论是整数还是实数,只要在允许的范围内都能准确无误的表示。
B)C程序由主函数组成。
C)C程序由函数组成。
D)C程序由函数和过程组成。
答案:C
2.11 TURBO C中int类型变量所占字节数是
A)1 B)2 C)3 D)4
答案:B
2.12 不合法的八进制数是
A)0 B)028 C)077 D)01
答案:B
2.13 不合法的十六进制数是
A)oxff B)0Xabc C)0x11 D)0x19
答案:A
二、填空题
2.14 若k为int整型变量且赋值11。请写出运算k++后表达式的值A)_____和变量的值B)_____。
答案:11、12
2.15 若x为double型变量,请写出运算x=3.2,++x后表达式的值A)_____和变量的值B)_____。
答案:4.2、4.2
2.16 函数体由符号____开始,用符号____结束。函数体的前面是____部分,其后是____部分。
答案:{、}、定义、执行
2.17 C语言中的标识符可分为____、____、和预定义标识符三类。
答案:关键字、用户标识符
2.18 在C语言程序中,用关键字____定义基本整型量,用关键字____定义单精度实型变量,用关键字___定义双精度实型变量。
答案:int、float、double
2.19 把a1、a2定义成单精度实型变量,并赋初值1的定义语句是____。
答案:float a1=1.0,a2=1.0;
2.20 C程序中定义的变量,代表内存中的一个____。
答案:存储单元
2.21 表达式3.5+1/2的计算结果是____。
答案:3.5
2.22 对以下数学式,写出三个等价的C语言表达式____、____、____。
a×b
——
c
答案:a*b/c、a/c*b、b/c*a
2.23 表达式s=10应当读做“____”。
答案:将10赋给变量s
2.24 计算机中内存储器的最小存储单位称____,其中能容纳的数是____。
答案:位、0或1
2.25 通常一个字节包含____个二进制位。在一个字节中能存放的最大(十进制)整数是____,它的二进制数的形式是____;最小(十进制)整数是____,它的二进制数的形式是____。
答案:8、255、1111 1111、-128、1000 0000
2.26 当计算机用两个字节存放一个整数时,其中能存放的最大(十进制)整数是____、最小(十进制)整数是____,它的二进制数的形式是____。
答案:65535、-32768、1000 0000 0000 0000
2.27 在C语言中整数可用____进制数、____进制数和____进制数三种数制表示。
答案:十、八、十六
三、 上机改错题
2.24 【分析与解答】
第1行的错误:
(1) include是一个程序行,因此在此行的最后不应当有分号(;)。
(2) include程序行中后面的stdio.h是一个文件名,按规定,文件名应当放在一对双引号(″ ″)一对尖括号(< >)内。
内,或放在
第2行的错误:
(1) main()是主函数的起始行,不是语句,因此最后不应当有分号(;)。
(2) 在同一行上的/ * main function * / 显然是注释;C语言规定:注释由/*开头,由*/结束,但在*号和/之间不得插入任何空格,而在此处“/ *”和“/ *”之间存在空格,因此,/ * main function
* /的写法式是错误的,而应写成:/* main function */。
第3行的错误:
(1) 在主函数的起始行main()的后面是函数体,函数体由左花括号({)开始。但在函数体的第一行:float的前面缺少了左花括号({)。
(2) 在同一行上的/* /*r is radius*/, /* s is area of circular*/ */ 显然是注释;C语言规定:注释由/*开头,由*/结束,并且开头的/*将去找最近的*/去配对,因此在/* /*r is radius*/中,第一个/*与最后的那个*/配上了对,结果紧跟在后面的那个逗号(,)落在了注释的外面,而构成了一个多余符号,为此,在编译时将报告“语法错”。
第6行的错误:
(1) printf(″%f \[KG-*3]n″,s)应当是一条输出语句,但在最后缺少了一个分号。
(2) printf(″%f \[KG-*3]n″,s);是程序的最后一条语句,程序应当结束;但缺少了程序体结束所需的右花括号(});此右花括号可以放在printf(″%f \[KG-*3]n″,s);的后面,也可以放在printf(″%f \[KG-*3]n″,s);的下一行上。
2.25 【分析与解答】
第1行的错误:在include行中的文件名应该是stdio.h,而不是stdio.a。
第2行的错误:在main的后面缺少一对圆括号。
第4行的错误:在c=40的后面缺少分号。
第6行的错误:在printf(″%f \〖KG-*3〗n″,v)的后面缺少分号。
第三章、顺序结构
一、选择题
3.1 若a、b、c、d都是int类型变量且初值为0,以下选项中不正确的赋值语句是
A) a=b=c=100; B) d++; C) c+b; D) d=(c=22)-(b++);
答案:C
3.2 以下选项中不是C语句的是
A) {int i; i++; printf("%dn", i); }
B) ; C) a=5,c=10 D) { ; }
答案:C
3.3 以下合法的C语言赋值语句是
A) A=B=58 B) k=int(a+b); C) a=58,b=58 D) --i;
答案:D
3.4 以下程序的输出结果是
A) 0 B) 1 C) 3 D)不确定的值
main()
{
int x=10,y=3;
printf("%dn", y=x/y);
}
答案:C
3.5 若变量已正确说明为int类型,要给a、b、c输入数据,以下不正确的输入语句是
A) read(a,b,c); B) scanf("%d%d%d",a,b,c);
C) scanf("%D%D%D",&a,&b,&c); D) scanf("%d%d%d",&a,&b,&c);
答案:D
3.6 若变量已正确说明为float类型,要通过以下赋值语句给a赋予10、b赋予22、c赋予33,以下不正确的输入形式是
A) 10
22
scanf("%f %f %f", &a, &b, &c);
答案:B
3.7 若变量以正确定义,要将a和b中的数进行交换,下面不正确的语句组是
A) a=a+b,b=a-b,a=a-b; B) t=a,a=b,b=t;
C) a=t; t=b; b=a; D) t=b; b=a; a=t;
答案:C
3.8 若变量已正确定义,以下程序段的输出结果是
A) 输出格式说明与输出项不匹配,输出无定值
B) 5.17000 C) 5.168000 D) 5.169000
x=5.16894;
printf("%fn",(int)(x*1000+0.5)/(float)1000);
答案:D
3.9 若有以下程序段,c3中的值是
A) 0 B) 1/2 C) 0.5 D) 1
int c1=1,c2=2,c3;
c3=c1/c2;
答案:A
3.10 若有以下程序段,其输出结果是
A) 0,0,-10 B) 0,0,5 C) -10,3,-10 D) 3,3,-10
int a=0,b=0,c=0;
c=(a-=a-5),(a=b,b+3);
printf("%d,%d,%dn",a,b,c);
答案:B
3.11 当运行以下程序时,在键盘上从第一列开始输入9876543210
A) a=98,b=765,c=4321 B) a=10,b=432,c=8765
C) a=98,b=765.000000,c=4321.000000 D) a=98,b=765,c=4321.0
main()
{
int a; float b,c;
scanf("%2d%3f%4f",&a,&b,&c);
printf("na=%d,b=%f,c=%fn",a,b,c);
}
答案:C
3.12 以下程序的输出结果是
A) a=%2,b=%5 B) a=2,b=5 C) a=%%d,b=%%d D) a=%d,b=%d
main()
{ int a=2,b=5;
printf("a=%%d,b=%%dn",a,b);
}
答案:D
3.13 若int类型占两个字节,则以下程序段的输出是
A) -1,-1 B) -1,32767 C) -1,32768 D) -1,65535
int a=-1;
printf("%d,%un",a,a);
答案:D
3.14 以下程序段的输出是
A) *496 * B) * 496* C) *000496* D)输出格式符不合法
int x=496;
printf("*%-06d*n",x);
答案:A
3.15 以下程序段的输出是
A) |3.1415| B) | 3.0| C) | 3| D) | 3.|
float a=3.1415;
printf("|%6.0f|n",a);
答案:C
3.16 以下程序段的输出是
A) |2345.67800| B) |12345.6780| C) |12345.67800| D) |12345.678|
printf("|%10.5f|n",12345.678);
答案:C
3.17 以下程序段的输出是
A) *0000057.66* B) * 57.66* C) *0000057.67* D) * 57.67*
float a=57.666;
printf("*%010.2f*n",a);
答案:C
3.18 若从终端输入以下数据,要给变量C赋以283.19,则正确的输入语句是
A) scanf("%f",c); B) scanf("%8.4f",&c);
C) scanf("%6.2f",&c); D) scanf("%8",&c);
283.1900
答案:由于印刷错误,本题没有正确答案。改正意见:
把选项A改为:scanf("%f",&c);或者把选项D改为:scanf("%8f",&c);则可分别选择A或者D为正确答案。
3.19 若变量已正确说明,要求用以下语句给a赋予3.12、给b赋予9.0,则正确的输入形式是(□代表空格)
A) 3.12□□9.0
C) a=3.12,b=9
scanf("a=%f,b=%f",&a,&b);
答案:C
3.20 以下程序的输出结果是
A) 9 8 B) 8 9 C) 6 6 D) 以上三个都不对
#include "math.h"
main()
{ double a=-3.0, b=2;
printf("%3.0f %3.0fn",pow(b,fabs(a)),pow(fabs(a),b));
}
答案:B
二、填空题
3.21 若有以下定义,请写出以下程序段中输出语句执行后的输出结果。
(1)____(2)____(3)____
int i=-200,j=2500;
printf("(1) %d %d",i,j);
printf("(2) i=%d, j=%dn",i,j);
printf("(3) i=%dn j=%dn",i,j);
答案:
-200 2500
i=-200, j=2500
i=-200
j=2500
3.22 变量i、j、k已定义为int类型并有初值0,用以下语句进行输入时
scanf("%d",&i); scanf("%d",&j); scanf("%d",&k);
当执行第一个输入语句,从键盘输入:
12.3
则变量i、j、k的值分别是____、____、____。
答案:12、0、0
3.23 复合语句在语法上被认为是____。空语句的形式是____。
答案:一条语句、 ;
3.24 C语句的最后用____结束。
答案:;
3.25 以下程序段,要求通过scanf语句给变量赋值,然后输出变量的值。写出运行时给k输入100,给a输入25.81,给x输入1.89234时的三种可能的输入形式____、_____、____。
int k; float a; double x;
scanf("%d%f%lf",&k,&a,&x);
printf("k=%d,a=%f,x=%fn",k,a,x);
答案:
(1) 100 25.81 1.89234
(2) 100 25.81
(3) 100
3.26 以下程序段的输出结果是____。
int x=0177;
printf("x=%3d,x=%6d,x=$%6o,x=%6x,x=%6un",x,x,x,x,x);
答案:x=127,x= 127,x= 177,x= 7f,x= 127
3.27 以下程序段的输出结果是____。
int x=0177;
printf("x=%-3d,x=%-6d,x=$%-06d,x=$%06d,x=%%06dn",x,x,x,x,x);
答案:27、x=127,x=127 ,x=$127 ,x=$000127,x=%06d
3.28 以下程序段的输出结果是____。
double a=513.789215;
printf("a=%8.6f,a=%8.2f,a=%14.8f,a=%14.8lfn",a,a,a,a);
答案:a=513.789215,a= 513.79,a= 513.78921500,a= 513.78921500
三、 编程题和改错题
3.16 【分析与解答】
(1) 主函数名main后应有一对圆括号。
(2) 变量定义语句中,v的前面缺逗号。
(3) 第三行的printf语句用以提示输入,但是原样输出的字符串没有用双引号括起来;另外,从输入的形式看,
输入的数据紧跟在提示之后,因此,printf格式串中最后不应该有换行符——\n。
(4) 因为输入项a、b、c从定义和计算结果来看都是double类型,因此,第四行scanf语句格式串中的格式说明不应当用%d而应当用%lf;且每一个变量之前应该加地址运算符&。
(5) 第七行的printf语句中应当把%d都改成%lf或%f;按输出要求在格式串中应添加相应的原样输出的字符;因为下一个printf的输出从新的一行开始,因此在本输出语句的格式串的最后应当加换行符——\n。
(6) 第八行的printf语句中应当把格式串整理合并放在输出项的前面,输出项放在后面,%d都改成%lf或%f;中间的\n删去。
(7) 请读者自己写出修改后的程序,并上机调试。
3.17【分析与解答】
(1) 分析:可用算术式560÷60把分钟换算成小时和分钟,商数就是小时数,余数就是分钟数。
(2) 确定变量的名字和定义变量的类型:在程序中把小时数放在变量h中,把分钟数放在变量m中。这两个变量的类型可以是整型(本题中采用整型),也可以是实型。
(3) 确定所用算法:求〖SX()560〖〗60〖SX〗〗的商数,在C语言中可以用整除的算法,语句是h=560/60;。求余数可用求余运算符 %:560%60,其值放入变量m中的语句是:m=560%60;。(4) 设计输出格式。若输出的形式定为:小时:分钟,则按此形式设计输出语句。
(5) 把以上内容放在主函数的一对花括号中。
(6) 编写程序如下:
main()
{ int h, m;
h=560/60;
m=560%60;
printf(″The result: %3d : %3d\n″, h,m);
}
运行结果是:
The result: 9 : 20
3.18 【分析与解答】
(1) 确定变量的名字和定义变量的类型。若用a存放1500,用b存放350;用q存放商数,用r存放余数,所有变量应定义成int类型。
(2) 设计输入语句从终端输入1500和350;在输入语句之前,应当设计一个输出语句,用以提示输入。
(3) 可用整除求商数,结果放在变量q中。可用求余运算符%求两数之余数,结果放在变量r中。
(4) 设计输出语句。输出a、b、q、r。
(5) 把以上内容放在主函数的一对花括号中。
本题的程序与3.30相似,请读者参考上题并根据本题的解释自己编程,并上机调试。
3.19 【分析与解答】
(1) 定义4个双精度变量a、b、c和ave,变量a、b、c分别存放读入的3个双精度数,ave存放它们的平均值。
(2) 设计输入语句,以及在此之前用于提示输入的(printf)语句。
(3) 设计求平均值的算法,把所求得的平均值放入变量ave中。
(4) 设计把变量ave中的数,从小数点后第二位数进行四舍五入的算法。现举例说明:若ave中的数为123.4644,为了保留此值小数点后一位,可用表达式:(int)(123.4644*10)/10.0;依次推算,为了保留此值小数点后二位,可用表达式:(int)(123.4644*100)/100.0;其他依此类推。
(5) 若要求对小数点后第二位数进行四舍五入,则可对原数加0.05后再进行以上运算。如要求保留123.4644小数点后一位且对第二位数进行四舍五入,可用表达式:(int)((123.467+0.05)*10)/10.0。注意:分母一定要用实数10.0而不能用整数10,否则就变成整除了;若要求保留123.4644小数点后两位且对第三位数进行四舍五入,可用表达式:(int)((123.467+0.005)*100)/100.0;其他依此类推。
(6) 设计输出语句。输出a、b、c和ave。
(7) 把以上内容放在主函数的一对花括号中。
(8) 编写程序如下:
main()
{ double a,b,c,ave;
printf(″Enter a ,b ,c : ″);
scanf(″%lf%lf%lf″, &a, &b, &c );
ave=(a+b+c)/3;
printf(″ave=%f\n″, ave); /*用以比较四舍五入前后的数据*/
ave=(int)((ave+0.05)*10)/10.0;
printf(″a=%f, b=%f, c=%f, ave=%f\n″, a,b,c,ave);
}
3.20 【分析与解答】
(1) 关于对变量中的数进行交换的算法请参考3.7题中的解释和《教程》中有关的例题。
(2) 定义4个整型变量a、b、c和t,变量a、b、c分别存放读入的3个整数,t用作临时存储单元。
(3) 设计输入语句,以及在此之前用于提示输入的(printf)语句。
(4) 输出a、b、c中的值,以便于比较。
(5) 交换的步骤如下:
① 把c中的值赋给t。
② 把b中的值赋给c。
③ 把a中的值赋给b。
④ 把t中的值赋给a。
经过以上步骤,已按要求进行了交换。
(6) 输出a、b、c中的值。
(7) 编写程序如下:
main()
{ int a, b, c, t;
printf(″Enter a, b, c :\n″);
scanf(″%d%d%d″,&a,&b,&c);
printf(″(1) a=%d,b=%d,c=%d\n″,a,b ,c);
t=c; c=b; b=a; a=t;
printf(″(2) a=%d,b=%d,c=%d\n″,a,b,c);
}
第四章、选择结构
一、 选择题
4.1 下列运算符中优先级最高的运算符是
A) ! B) % C) -= D) &&
答案:A
4.2 下列运算符中优先级最低的运算符是
A) || B) != C) <= D) +
答案:A
4.3 为表示关系x≥y≥z,应使用的C语言表达式是
A) (x>=y)&&(y>=z) B) (x>=y)AND(y>=z)
C) (x>=y>=z) D) (x>=y)&(y>=z)
答案:A
4.4 设a、b和c都是int型变量,且a=3,b=4,c=5;则以下的表达式中,值为0的表达式是 A) a&&b B) a<=b C) a||b+c&&b-c
|1)
答案:D
4.5 以下程序的输出结果是
A) 0 B) 1 C) 2 D) 3
main()
{ int a=2,b=-1,c=2;
if(a
if(b<0) c=0;
else c+=1;
printf("%dn",c);
}
D) !((a
答案:C
4.6 以下程序的输出结果是
A)1 B) 2 C) 3 D) 4
main()
{ int w=4,x=3,y=2,z=1;
printf("%dn",(w } 答案:A 4.7 若执行以下程序时从键盘上输入3和4,则输出结果是 A) 14 B) 16 C) 18 D) 20 main() { int a,b,s; scanf("%d%d",&a,&b); s=a; if(a s*=s; printf("%dn",s); } 答案:B 4.8 下面的程序片段所表示的数学函数关系是 -1(x<0) A) y= 0(x=0) 1(x>0) 1(x<0) B) y= -1(x=0) 0(x>0) 0(x<0) C) y= -1(x=0) 1(x>0) -1(x<0) D) y= 1(x=0) 0(x>0) y=-1; if(x!=0) y=1; if(x>0) y=1; else y=0; 答案:A 4.9 运行以下程序后,输出 A) **** B) &&&& C) ####&&&& D) 有语法错误不能通过编译 main() { int k=-3; if(k<=0) printf("****n") else printf("&&&&n"); } 答案:D 4.10 若a和b均是正整型变量,以下正确的switch语句是 A) switch(pow(a,2)+pow(b,2)) { case 1: case 3: y=a+b; break; case 0: case 5: y=a-b; } B) switch(a*a+b*b); { case 3: case 1: y=a+b; break; case 0: y=b-a; break; } C) switch a { default: x=a+b; case 10: y=a-b; break; case 11: x=a*d; break; } D) switch (a+b) { case10 : x=a+b; break; case11 : y=a-b; break; } 答案:没有正确答案。如果C选项改为: switch(a) { default: x=a+b; case 10: y=a-b; break; case 11: x=a*b; break; } 则答案可以选择C 二、填空题 4.11 C语言中用____表示逻辑值“真”,用____表示逻辑值“假”。 答案:非0、0 4.12 C语言中的关系运算符按优先级别是____、____、____、____。 答案:>、<、>=、<=、==、!= 4.13 C语言中的逻辑运算符按优先级别是____、____、____。 答案:!、&&、|| 4.14 C语言中的关系运算符和逻辑运算符的优先级别是____、____、____、____、____、____、____。 答案:!、<、>、==、!=、&&、|| 4.15 C语言中逻辑运算符____的优先级高于算术运算符。 答案:! 4.16 将下列数学式改写成C语言的关系表达式或逻辑表达式A)____B)____。 A)a=b或a 答案:A)a==b||a 4.17 请写出以下程序的 输出结果____。 main() { int a=100; if(a>100) printf("%dn",a>100); else printf("%dn",a<=100); } 答案:1 4.18 请写出与以下表达式等价的表达式A)____B)____。 A) !(x>0) B) !0 答案:A) x<=0 B) 1 4.19 当a=1,b=2,c=3时,以下if语句执行后,a、b、c中的值分别为____、____、____。 if(a>c) b=a; a=c; c=b; 答案:3、2、2 4.20 若变量已正确定义,以下语句段的输出结果是____。 x=0; y=2; z=3; switch(x) { case 0: switch(y==2) { case 1: printf("*"); break; case 2: printf("%"); break; } case 1: switch(z) { case 1: printf("$"); case 2: printf("*"); break; default : printf("#"); } } 答案:*# 三、 编程题 4.21 【分析与解答】 相关内容请参考《教程》4.2节和4.4节。 (1) 改写如下: switch(a/10) { default : m=5; break; case 0 : case 1 : case 2 : m=1; break; case 3 : m=2; break; case 4 : m=3; break; case 5 : m=4; break; }; (2) 本题中对a的判断条件有一定的规律可寻;关键是,在switch语句后的表达式中利用了a/10,从而简化了case标号。 4.22 【分析与解答】 编写本题的程序,首先要解决如何计算学生当前的年龄(设存放实足年龄的变量是age)。 (1) 如果当前的月份大于生日的月份,则学生的实足年龄age=y1-y0。 (2) 如果当前的月份等于生日的月份,就要看日数,当前的日数大于或等于生日的日数,则学生的实足年龄age=y1-y0。 (3) 如果不满足以上的条件,就可断定当前的日期没有超过生日日期,就是说学生的年龄应当是age=y1-y0-1。 以上3条,用C语言可以描述如下: if((m1>m0)[JB>1|][JB>1|](m1==m0&&d1>=d0)) age=y1-y0; else age=y1-y0-1; 读者可以参考以上语句写出程序,也可以根据分析写出与此形式不同的语句和程序。 4.23【分析与解答】 (1) 若输入的整数a是奇数,输出 dd number,是偶数输出:even number。 (2) 若一个a是偶数,它就能被2除尽,即a%2==0,输出even number;若是奇数, 它就不能被2除尽,即a%2!〖KG-*2〗=0,输出odd number。 读者可以参考以上给出的算法,写出相应的C语句,并编写出完整的程序。 4.24 【分析与解答】 本题的主要算法是从3个数中找出最大的那个数。假定始终把最大的数放在变量max中。 (1) 假定a中的数最大,把a赋给max。 (2) 用b去和max比较,若b大于max,则把b赋给max;若不大于max,则什么也不做。 (3) 用c去和max比较,若c大于max,则把c赋给max;若不大于max,则什么也不做。 (4) 经过以上操作,max中已放入了a、b、c三个数中的最大数,输出max即可。 读者可以参考以上给出的算法,写出相应的C语句,并编写出完整的程序。 4.25 【分析与解答】 (1) 本题已给出了非常明确的条件,只要写出正确的条件判断语句就可基本完成程序的编写。 (2) 由给出的函数可知,只有x的值在规定的范围内时,才求出y的值,因此程序应当对输入的x进行判断,若超过范围就不求y的值。 (3) 现以使用if[CD#*2]else语句为例写出程序供参考。 main() { int x,y; printf(″Enter x : ″); scanf(″%d″, &x); if(x>-5&&x<10) { if(x==0) y=x-1; else if(x<10 && x>0 ) y=x+1; else if(x<0 && x>-5) y=x; printf(″x=%d y=%d\n″, x,y); } printf(″***END***\n\n″); } 第五章、循环结构 一、 选择题 5.1 以下程序段的输出结果是 A) 9 B) 1 C) 11 int k,j,s; for(k=2; k<6; k++,k++) { s=1; for(j=k; j<6; j++) s+=j; } printf("%dn", s); 答案:D 5.2 以下程序段的输出结果是 A) 12 B) 15 C) 20 int i,j,m=0; for(i=1; i<=15; i+=4) for(j=3; j<=19; j+=4) m++; printf("%dn", m); 答案:C 5.3 以下程序段的输出结果是 A) 10 9 8 B) 9 8 7 C) 10 9 8 7 D) 9 D) 10 D) 25 8 7 6 int n=10; while(n>7) { n--; printf("%dn", n); } 答案:B 5.4 以下程序段的输出结果是 A) 1 B) 3 0 C) 1 -2 int x=3; do { printf("%3d",x-=2); } while(!(--x)); 答案:C 5.5 以下程序段的输出结果是 A) 15 B) 14 C) 不确定 main() { int i,sum; for(i=1; i<6; i++) sum+=sum; printf("%dn",sum); } 答案:C 5.6 以下程序段的输出结果是 A) 741 B) 852 C) 963 main() { int y=10; for(; y>0; y--) if(y%3==0) { printf("%d", --y); continue; } 答案:B 5.7 若x是int型变量,以下程序段的输出结果是 A) **3 ##4 **5 B) ##3 **4 ##5 C) ##3 **4##5 D) **3##4 **5 for(x=3; x<6; x++) printf((x%2)?("**%d"):(##%dn"),x); D) 死循环 D) 0 D) 875421 } 答案:D 5.8 以下程序的输出结果是 A) *#*#*#$ B) #*#*#*$ C) *#*#$ D) #*#*$ main() { int i; for(i=1; i<=5; i++) { if(i%2) printf("*"); else contionue; printf("#"); } printf("$n"); } 答案:A 5.9 以下叙述正确的是 A) do_while语句构成的循环不能用其它语句构成的循环来代替。 B) do_while语句构成的循环只能用break语句退出。 C) 用do_while语句构成循环时,只有在while后的表达式为非零时结束循环。 D) 用do_while语句构成循环时,只有在while后的表达式为零时结束循环。 答案:D 5.10 以下程序的输出结果是 A) 39 81 B) 42 84 C) 26 68 D) 28 70 main() { int x,i; for(i=1; i<=100; i++) { x=i; if(++x%2==0) if(++x%3==0) if(++x%7==0) printf("%d ", x); } printf("n"); } 答案:D 二、 填空题 5.11 当执行以下程序段后,i的值是____、j的值是____、k的值是____。 int a,b,c,d,i,j,k; a=10; b=c=d=5; i=j=k=0; for( ; a>b; ++b) i++; while(a>++c) j++; do k++; while(a>d++); 答案:5、4、6 5.12 以下程序段的输出结果是____。 int k,n,m; n=10; m=1; k=1; while(k<=n) m*=2; printf("%dn",m); 答案:死循环 5.13 以下程序的输出结果是____。 main() { int x=2; while(x--); printf("%dn",x); } 答案:-1 5.14 以下程序段的输出结果是____。 int i=0,sum=1; do { sum+=i++; }while(i<5); printf("%dn",sum); 答案:11 5.15 有以下程序段: s=1.0; for(k=1; k<=n; k++) s=s+1.0/(k*(k+1)); printf("%fn",s); 请填空,使下面的程序段的功能完全与之等同。 s=0.0; ____; k=0; do { s=s+d; ____; d=1.0/(k*(k+1)); } while(____); printf("%fn",s); 答案:d=1.0、k++、k<=n 5.16 以下程序的功能是:从键盘上输入若干个学生的成绩,统计并输出最高成绩和最低成绩,当输入负数时结束输入。请填空。 main() { float x,amax,amin; scanf("%f",&x); amax=x; amin=x; while(____) { if(x>amax) amax=x; if(____) amin=x; scanf("%f",&x); } printf("namax=%fnamin=%fn",amax,amin); } 答案:x>=0、x 三、 编程题 5.17【分析与解答】 (1) 本题的基本算法是求累加值。累加项的值有规律的递增,每一项的绝对值比前一项增2,因此可以利用循环的控制变量的递增来得到累加项的绝对值。例如: for( i=1; i<=101; i+=2 )… (2) 按所给的算式可以看到,累加项的符号是在交叉改变的,为此应当在循环体内设 置一个变量,使它的符号按此规律交叉改变,这可用:s=-s;来实现,s的初值为1;当s的值为1时,赋值后s中新的值为-1,当s的值为-1时,赋值后s中新的值为1。用s去乘累加项,将使累加项的符号也随之有规律地改变。 (3) 若累加和放在变量sum中,累加项放在变量t中,按照以上叙述,for循环体内的语句可以设计如下: s=-s; t=s*i; sum=sum+t; (4) sum的值是51。 (5) 请读者自己对变量做出正确的定义并赋初值,设计输出语句,完善程序。 5.18 【分析与解答】 (1) 本题的基本算法是求累加值。累加项的分子部分都是1;分母的值有规律的递增,依次为1!、2!、…、n!,即,若第i-1项的累加项为 t(i-1),则第i项的累加项是 t( i-1)*i,在程序中可用表达式:t=t/i(i从1变化到n)来表示。 (2) 根据以上分析,若用变量t来存放累加项,当i的值从1变化到n时,可用以下语句来实现累加: t=t/i; e+=t; (3) 为了实现累加过程,以上语句应当放在循环内,循环控制变量从1变化到n。 (4) 若用for循环,按题目要求已指定n的值是50。若用while循环,并没有指定n的值,但已指定了循环结束的条件,当t的值小于10-4结束循环。 (5) 现例示用while循环来求e值的部分程序: i=1; e=1.0; t=1.0; while( t>=1e-4 ) { t=t/i; e+=t; i++; } (6) 请读者自己对变量做出正确的定义,设计输出语句,完善程序;也可以参考此程序段, 按照自己的思路独立地完成程序。 (7) e的值应当是:2.71828。 (8) 根据以上分析,读者已不难用for循环来实现求e值的计算。 (9) 注意:在完成此程序时,不要对分母中的阶乘值进行单独计算,因为17!的值已超过long类型的最大值,更无法求到50!。 5.19【分析与解答】 (1) 从1880年至2000年的年数可用一个for循环来取得。 (2) 对每一年,用以上指定的条件来进行判断,若满足条件即为闰年,进行输出。 (3) 按输出的要求,需要设一个变量用于统计一行中输出的个数,若在一行上已连续输出了5个年数,就需输出一个换行符,使下一个输出项在新的一行上开始;若用变量n来做此统计,则当表达式n%5==0时就应输出一个换行符,同时使n重新置0值。 (4) 若变量y代表年数,if语句的逻辑表达式可以写成如下: (y%4==0 && y%100!=0[JB>1|][JB>1|]y%400==0) (5) 以下程序段供参考: for ( y=1880; y<=2000; y++ ) if(y%4==0 && y%100![KG-*2]=0[JB>1|][JB>1|]y%400==0) { printf(″%d ″,y); n++; if(n%5==0) { printf(″\n″); n=0; } } (6) 请读者自己对变量做出正确的定义并赋初值,完善程序;也可以参考此程序段,按照自己的思路独立地完成程序。从1880年至2000年有30个闰年。 5.20 【分析与解答】 (1) 不难理解利用以下的for循环可以在一行上连续输出n个*号: for(i=1; i<=n; i++) printf(″*″); printf(″\n″); 若n的值是6,则连续输出6个*号。 (2) 以上图形是在各行上输出数目不等的*号,只是*号的数目依次有规律地变化。在上半部分各行依次是1、3、5、7个,因此可以用以下的程序段来实现这样的输出: for(k=1;k<=7;k++,k++) { for(i=1;i<=k; i++)printf(″*″); printf(″\n″); } 在下半部依次是5、3、1个;因此可以用以下的程序段来实现这样的输出: for(k=5;k>=1;k--,k--) { for(i=1;i<=k; i++)printf(″*″); printf(″\n″); } 以上程序段从第一列起输出的结果如下:* *** ***** ******* ***** *** * 现在我们已完成了在每行输出指定数目的*号。 (3) 输出结果与题目要求不同,它们的区别是:按题目每一行之前有不同的空格,而这里则是所有的行都在第一列上开始输出*号;所以接着就应当解决这一问题。 (4) 分析题目要求,每行第一个*号位置的缩进是有规律的,假定中间这一行第一个*号位置是在第一列,则可看出,第一至第三行的缩进分别是3、2、1个空格;而图形下半部的缩进数则刚好相反。这可在以上循环中添加输出连续空格的for循环来实现,对于上半部程序如下: b=3; for(k=1;k<=7;k++,k++) { for(j=1;j<=b; j++)printf(″ ″); b--; for(i=1;i<=k; i++)printf(″*″); printf(″\n″); } (5) 请读者在理解以上给出的示例的基础上,自己添加下半部空格的输出。 第六章、字符型数据 一、选择题 6.1 C语言中的简单数据类型有 A) 整型、实型、逻辑型 B) 整型、实型、字符型 C) 整型、字符型、逻辑型 D) 整型、实型、逻辑型、字符型 答案:B 6.2 C语言中,字符(char)型数据在微机内存中的存储形式是 A) 反码 B) 补码 C) EBCDIC码 D) ASCII码 答案:D 6.3 设有语句char a=''72'';,则变量a A) 包含1个字符 B) 包含2个字符 C) 包含3个字符 D) 说明不合法 答案:A 6.4 C语言中不合法的字符常量是 A) ''0xff'' B) ''65'' C) ''&'' D) ''028'' 答案:本题A)和D)选项都是不合法的字符常量。若A)选项改为''xff'',则正确。 6.5 C语言中不合法的字符串常量是 A) "121" B) ''y='' C) "nn" D) "ABCDx6d" 答案:B 6.6 判断char型变量c是否为大写字母的最简单且正确的表达式是 A) ''A''<=c<=''Z'' B) (c>=''A'')&(c<=''Z'') C) (''A''<=c)AND(''Z''>=c) D) (c>=''A'')&&(c<=''Z'') 答案:D 6.7 以下程序的输出结果是 A) 因输出格式不合法,无正确输出 B) 65,90 C) A,Y D) 65,89 main() { char c1=''A'',c2=''Y''; printf("%d,%dn",c1,c2); } 答案:D 6.8 以下程序段的输出结果是 A) A B) a C) Z D) z main() { char x=''A''; x=(x>=''A''&&x<=''Z'')?(x+32):x; printf("%cn",x); } 答案:B 6.9 以下程序的输出结果是 A) 67,C B) B,C C) C,D D) 不确定的值 main() { char ch1,ch2; ch1=''A''+''5''-''3''; ch2=''A''+''5''-''3''; printf("%d,%cn",ch1,ch2); } 答案:A 6.10 对以下程序,从第一列开始输入数据:2473 A) 668977 B) 668966 C) 66778777 D) 6688766 #include "stdio.h" main() { int c; while((c=getchar())!=''n'') { switch(c-''2'') { case 0 : case 1 : putchar(c+4); case 2 : putchar(c+4); break; case 3 : putchar(c+3); default : putchar(c+2); break; } printf("n"); } } 答案:A 6.11 若变量已正确说明,要求用以下语句给c1赋予字符%、给c2赋予字符#、给a赋予2.0、给b赋予4.0,则正确的输入形式是(□代表空格) A) 2.0□%□4.0□# C) 2%□□4# scanf("%f%c%f%c",&a,&c1,&b,&c2); ( 答案:B 二、填空题 6.12 EOF的十进制值是____。 答案:-1 6.13 C语言中,字符占内存____个字节。 答案:1 6.14 调用C语言对字符处理的库函数时,在#include命令行中应包括的头文件是____。 答案:string.h 6.15 若输入字符A,在以下while语句执行后ch的值是____。 while(ch=getchar()==''A''); 答案:1 6.16 若要通过以下语句给a、b、c、d分别输入字符A、B、C、D,给w、x、y、z分别输入10、20、30、40,正确的输入形式是____,请用 scanf("%d%c%d%c%d%c%d%c",&w,&a,&x,&b,&y,&c,&z,&d); 答案:10A20B30C40D 6.17 若有以下说明和输入语句,要求给c1、c2输入字符A和B,给a1、a2输入7.29和101.298,从键盘正确输入数据的形式是____。 char c1,c2; float a1,a2; scanf("%f%f",&a1,&a2); scanf("%c%c",&c1,&c2); 答案:7.29 6.18 若有以下说明和输入语句,要求给c1、c2输入字符A和B,给a1、a2输入7.29和101.298,从键盘正确输入数据的形式是____。 char c1,c2; float a1,a2; scanf("%c%f%c%f",&c1,&a1,&c2,&a2); 答案:A7.29B101.298 6.19 若有以下说明和输入语句,要求给c1、c2、c3输入字符A、B和C,请写出各种从键盘正确输入数据的形式。 char c1,c2,c; scanf("%4c",&c1); scanf("%4c",&c2); scanf("%4c",&c3); 答案:A□□□B□□□C□□□ 三、 编程题 6.20【分析与解答】 (1) 在进行字符输入时,即使一次输入了一行字符(最后用回车结束输入),字符也只能一个一个地读入。若ch已定义为char型变量,可以用以下的程序段来完成操作: ch=getchar(); while(ch![KG-*2]=′\n′) { …… ch=getchar(); } 当读入的是一个回车符时,循环就结束。循环体内的“……”符号表示需要在循环体内完成的其他操作。 (2) 在循环内要求进行的操作之一是:输出每个字符以及与之对应的ASCII代码值。因此可用以下语句来实现。 printf(″%c : %d ″,ch,ch); (3) 在循环内要求进行的另一个操作是:每行只能输出3对字符和与之对应的ASCII代码值。若n已定义为int型变量,则可用来作计数器;使n的初值为0,每输出一次,n的值增1,当n的值为3的整数倍时,额外输出一个换行符。例如: n++; if(n%3==0)putchar(′\n′); (4) 把(2)和(3)中给出的语句放在循环体内,并按要求给出正确的定义和初值,就可完成题目所要求的操作。 (5) 也可以在while后的一对括号中来完成字符的读入,如while((ch=getchar())![KG-*2]=′\n′)。这时,循环内、外的“ch=getchar();”语句应当去掉。 6.21【分析与解答】 (1) 一行字符的读入,请参照题6.20(1)和(5)中的解释。循环体内的“……”符号表示需要在循环体内完成的其他操作。 ch=getchar(); while(ch![KG-*2]=′\n′) { …… ch=getchar(); } (2) 在本题中循环体内需要把读入的所有数字字符转换成一个整数。若用变量n来存放这个整数,为了保证有效的存放,应当把它定义成long类型。 (3) 要把输入的一串数字字符转换成一个整数,首先需要判断当前读入的字符是否是数字字符,若不是则什么也不做;若是,则进行以下操作: ① 把当前读入的一个字符转换成一个一位整数,这可由语句“d=ch-′0′; ”来实现,在这里d是一个整型变量; ② 把d中的一位数归并到n的低位中,这可用语句“n=n*10+d;”来实现。这里所述的操作可由以下语句来完成: if(ch>=′0′&&ch<=′9′){ d=ch-′0′; n=n*10+d; } if语句后一对括号中的判断表达式可以调用字符函数isdigit来实现: if( isdigit(ch) ) { d=ch-′0′; n=n*10+d; } if子句的两个语句可以合并成:n=n*10+ch-′0′;。 (4) 把(3)中的语句放入循环中: ch=getchar(); while(ch![KG-*2]=′\n′) { if(ch>=′0′&&ch<=′9′) n=n*10+ ch-′0′; ch=getchar(); } (5) 请自己写出定义语句并赋初值。注意,最后输出n时,应当使用格式说明%ld,而不能使用%d。 6.22【分析与解答】 (1) 行数的统计可通过统计输入的′\n′符的个数来完成。 (2) 统计的过程应当放在一个while循环体中;判断循环是否进行的条件可以用:((ch=getchar())==EOF)。若用整型变量n作为计数器对′\n′符进行统计,只要读入的字符是′\n′,则n增1。如: while((ch=getchar())![KG-*2]=EOF) if(ch==′\n′)n++; (3) EOF是在stdio.h中预定义了的标识符,在TURBO C的环境下,键入Ctrl+Z(即按住键盘上的Ctrl键,同时按字母Z键)后,敲Enter键,即输入了EOF。 6.23【分析与解答】 (1) 本题要求的操作同样可在while循环中完成: while((ch=getchar())!=′\n′) { …… } (2) 若用整型变量n作为计数器对小写字母进行统计,只要读入的字符是小写字母,则n增1。如: if(ch>=′a′ && ch<=′z′)n++; (3) 在退出循环后,输出n的值。 (4) 请自己完善程序。 6.24【分析与解答】 (1) 若图案的行数输入到变量L中。 (2) 按要求L决定了图形的行数,因此可通过循环来实现L行的输出: for(i=1; i<=L; i++) { …… } 循环体中的“……”号,代表输出L行的操作。 (3) 假定ch中存放了一个字符,我们知道,通过以下循环可以在一行上输出n个字符: for(j=1; j<=n; j++)putchar(ch); putchar(′\n′); 注意,在循环后putchar(′\n′);语句不可少,它用以换行。 (4) 现在应当解决如何按要求给出每行输出的字符。由图分析,行数(或行号)为1时输出字符A,行数为2时输出字母B……若输出的字母放在变量ch中,行号取决于外循环的控制变量i,则输出的字母和行号的关系可用表达式:ch=′A′+i-1来表示。当i为1时ch中被赋予字母A,当i为2时ch中被赋予了字母B,其他依此类推。因此,在此表达式后,利用(3)中的循环就解决了各行上输出的字母。 (5) 按要求每行输出的字母的个数不同,第二行输出3个字母,第三行输出5个字母,第四行输出7个字母……(3)中for循环体的执行次数取决于n的值,也就是说n的值决定了每行输出字母的个数。其实,n的值与行号有着密 切的关系:n=2*i-1,当i为1时n的值是1、当i的2时n的值是3、当i的3时n的值是5、当i的4时n的值是7。因此在(3) 中for循环之前可用此表达式求出n的值。 (6) 总结以上分析,我们可得到以下的程序段: for(i=1; i<=L; i++) { ch=′A′+i-1; n=2*i-1; for(j=1; j<=n; j++)putchar(ch); putchar(′\n′); } 若所用的变量都已正确定义,通过输入L的值为5,则程序段在第一列起有以下的输出结果: A BBB CCCCC DDDDDDD EEEEEEEEE 和题目的要求比较已趋接近,不同的是在每行没有适当的缩进。 (7) 现在来解决每行的缩进问题。由题中给出的图形可知,若指定输出5行,第一行缩进5个空格,第二行则缩进4个空格,第三行则缩进3个空格,第四行则缩进2个空格,第五行则缩进1个空格。这同样可以由以下的for循环来实现: for(k=L; k>=i; k--)putchar(′ ′); 把此循环放在i控制的循环体内、输出每行字符的循环之前即可。 (8) 请读者自己补充有关的include行、语句和变量的定义,以完成整个程序。注意,如果有能力可在某些地方作些简化。 第七章、函数 一、选择题 7.1 以下说法中正确的是 A) C语言程序总是从第一个定义的函数开始执行 B) 在C语言程序中,要调用的函数必须在main函数中定义 C) C语言程序总是从main函数开始执行 D) C语言程序中的main函数必须放在程序的开始部分 答案:C 7.2 以下函数的类型是 A) 与参数x的类型相同 B) void类型 C) int类型 D) 无法确定 fff(float x) { printf("%dn",x*x); } 答案:C 7.3 以下函数调用语句中,含有的实参个数是 A) 1 B) 2 C) 4 D) 5 func( (exp1,exp2),(exp3,exp4,exp5)); 答案:B 7.4 以下程序的输出结果是 A) 11 B) 20 C) 21 D) 31 fun(int a,int b) { int c; c=a+b; return c; } main() { int x=6,y=7,z=8,r; r=func((x--,y++,x+y),z--); printf("%dn",r); } 答案:C 7.5 以下程序的输出结果是 A) -1 B) 0 C) 1 D) 2 main() { int i=2,p; p=f(i,i+1); printf("%d",p); } int f(int a, int b) { int c; c=a; if(a>b) c=1; else if(a==b) c=0; else c=-1; return(c); } 答案:A 7.6 以下程序的输出结果是 A) 0 B) 1 C) 6 D) 无定值 fun(int a,int b,int c) { c=a*b; } main() { int c; fun(2,3,c); printf("%dn",c); } 答案:D 7.7 以下程序的输出结果是 A) 5.500000 B) 3.000000 C) 4.000000 D) 8.25 double f(int n) { int i; double s; s=1.0; for(i=1; i<=n; i++) s+=1.0/i; return s; } main() { int i,m=3; float a=0.0; for(i=0; i printf("%fn",a); } 答案:A 二、 填空题 7.8 以下程序的输出结果是____。 unsigned fun6(unsigned num) { unsigned k=1; do { k*=num%10; num/=10; } while(num); return k; } main() { unsigned n=26; printf("%dn",fun6(n); } 答案:12 7.9 以下程序的输出结果是____。 double sub(double x,double y,double z) { y-=1.0; z=z+x; return z; } main() { double a=2.5,b=9.0; printf("%fn",sub(b-a,a,a)); } 答案:9.000000 7.10 以下程序的输出结果是____。 fun1(int a,int b) { int c; a+=a; b+=b; c=fun2(a,b); return c*c; } fun2(int a,int b) { int c; c=a*b%3; return c; } main() { int x=11,y=19; printf("%dn",fun1(x,y)); } 答案:4 7.11 下面pi函数的功能是,根据以下公式返回满足精度ε要求的π的值。请填空。 π/2 = 1 + 1/3 + (1/3)*(2/5) + (1/3)*(2/5)*(3/7) + (1/3)*(2/5)*(3/7)*(4/9) + ... double pi(double eps) { double s=0.0,t=1.0; int n; for(_____; t>eps; n++) { s+=t; t=n*t/(2*n+1); } return (2.0*_____); } 答案:n=1、s 7.12 以下函数用以求x的y次方。请填空。 double fun(double x, int y) { int i; double z; for(i=1; i_____; i++) z=_____; return z; } 答案:<=y、z*x 7.13 以下程序的功能是计算s=0!+1!+2!+3!+...+n!。请填空。 long f(int n) { int i; long s; s=_____; for(i=1; i<=n; i++) s=_____; return s; } main() { long s; int k,n; scanf("%d",&n); s=_____; for(k=0; k<=n; k++) s=s+_____; printf("%ldn", s); } 答案:1L、s*i、0、f(k) 三、 程序调试和编程题 7.14 【分析与解答】 (1) fun函数判断传给形参n的数是否为素数,若是函数返回1,否则返回0。 (2) 函数的原意是用变量yes作为判断n是否为素数的标志,是素数,其值为1,否则为0。而所给函数的实际流程却不能实现这一功能,例如,若n的值为15(明显不是素数)时,在for循环中,当k的值为3时,就会执行if子句,yes得0,但for循环并没有终止,接着k为4时就会执行else子句,又使yes得1,由此可见此程序段并不能准确地判断一个数是否为素数;最后确定yes为何值的是for循环的终止值n/2,当n为15时,k的值为n/2等于7,在循环体内将又一次执行else子句,使yes得1,这时循环结束,函数返回1。由此可见所给fun函数不能起到预想的作用。 (3) 由上分析可知,对于n的值为15时而言,问题是在一旦yes的值为0,已判断n中的值不是素数时,没有及时退出循环,返回0;因此,若在if子句中添加一条语句:break;就能解决这一问题,把if语句改写如下: if(n%k==0){ yes=0; break; } else yes=1; (4) 在所给fun函数中,当n的值为2、3时(都是素数),因为n/2的值为1(大于k中的2),所以不会进入for循环,而直接执行return语句,细心的读者应该可以发现,这时yes没有赋过值,也就是说,返回的是一个不确定的值,这将会导致错误;因此,应当在定义语句中给yes赋初值1: int k, yes=1; 至此fun函数能正确运行。 (5) 总结:因为一旦if语句中的表达式:n%k==0的值为1(即可被某数整除),则可以确定n不是素数,因此即可返回,不必再执行函数其他部分,if子句可改成: if(n%k==0){ yes=0; return yes; } else yes=1; 也可简化成: if (n%k==0) return 0; else yes=1; 又可进一步不用变量yes,并去掉else,简化成(请参考例7.4): for( k=2; k<=n/2; k++) if(n%k==0) return 0; return 1; 7.15【分析与解答】 (1) 若用整型变量c存放余数,则求a被b除后的余数可用表达式: c=a%b。 (2) 本题要求编写函数mymod用以求a被b除后的余数即: c=mymod( a,b ); (3) 只要把a%b作为函数值返回即可完成操作(请参考例7.1): int mymod(int a, int b) { return a%b; } (4) 总结:本题在算法上十分简单,只是要求读者能够掌握编写函数的基本知识。 7.16【分析与解答】 (1) 本题所要采用的算法是累加。分析可见,所有累加项的分子都是1,而分母部分逐项增1;只是累加项的符号交叉变化。因此处理好符号的变化是完成操作的关键之一。 (2) 若函数名为funa,传送到函数的参数是整型值,假定形参命名为n;函数的返回值应当是浮点型,为此函数的首部可以是: double funa( int n ) (3) 接着写函数体。累加放在一个for循环中来完成,若循环控制变量为k,可利用循环控制变量作为累加项t的分母,累加值放在add中: for( k=1; k<=n; k++) { …… t=s*1.0/k; add=add+t; } 此处,s用作符号变量,在1和-1之间交叉变化,乘以1.0/k后,t的值也将按要求变化符号。注意,表达式1.0/k不可以写成1/k,因为每一项的绝对值必定是小于1的小数。 (4) 现在需要确定s的值。最简单的可用表达式:s=-s来实现(请参考例5.2),若赋 值号右边s中的值为-1,则赋值号左边s中的值就得1;若赋值号右边s中的值为1,则赋值号左边s中的值就会得-1;则每循环一次就使s改变了一次符号。当然还可有多种方法。把以上表达式添加到循环体中: for( k=1; k<=n; k++) { s=-s; t=s*1.0/k; add=add+t; } (5) 最后注意应当给各变量赋以适当的初值,并返回函数值。 (6) 请编写主函数。当传给形参的值为10时,函数的返回值应当是:0.645635。 (7) 总结:本题的算法并不复杂,但是需要读者掌握编写函数的基本知识。掌握需要传入函。 数的参数及其类型,掌握需要返回的值及其类型。在此基础上,其他方面与先前在主函数中编写的程序没有什么区别。 7.17 【分析与解答】 (1) 此题与7.18相似。函数的返回值为浮点型,函数只有一个形参,为整型。 (2) 函数的基本算法是累加,只是除第一项外其余各项都用减法;每一项的分子都是1,分母部分为k值逐项增1,由2变化到m。因此,算法可以用一个循环来实现。 (3) 当m的值为12时,函数值应是:0.435023。 2,k的7.18【分析与解答】 (1) 若函数取名为fun,按题意,x作为形参,由调用函数传入,其类型不应当用整型;表达式x2-5x+4的值作为函数值返回,函数值的类型应为浮点型。因此,很容易写出函数: double fun( double x ) { return x*x-5*x+4; } (2) 若在调用函数时,x和y2已正确定义,且x已有确定的值,则可用以下函数调用语句得到y2的值: y2=fun( x+15 ); (3) 同样,若在调用函数时,x和y3已正确定义,且x已有确定的值,则可用以下函数调用语句得到y3的值: y3=fun( sin(x) ); 注意,因为在程序中调用了C语言提供的库函数sin,因此应当在程序的最前面包含以下命令行: #i nclude ″math.h″ (4) 参考(2) 和(3) 应不难写出求y1的语句,请读者自己完成。 (5) y1的值应是:-2.0。当x的值为5时,y2的值应是:304.0。当x的值为0.5时,y3的值应是:1.832721。 (6) 总结: ① 本题已给出了函数需要求值的表达式,读者只需确定函数的类型和形参的类型,就可以写出函数,就像例7.1中求两数之和的函数一样简单。 ② 在给定了函数之后,调用函数时,函数的实参应当是一个与形参类型一致的任意合法的 表达式。例如,可以是常量、算术表达式,也可以是函数等。就像例7.1中求两数之和的add函数一样,可以用add( 3,4 );来求3+4;当x、y有确定值时,可以用add( x*x,y*y);来求x2+y2;当x、y有确定值时,可以用add( sin(x+y),cos(x+y));来求sin(x+y)+cos(x+y),这同样可以通过add( sin(add(x,y)),cos((add(x,y)) );来求得。 第八章 指针 一、 选择题 8.1 若有定义:int x,*pb; 则以下正确的赋值表达式是 A) pb=&x B) pb=x C) *pb=&x 答案: A 8.2 以下程序的输出结果是 A) 因变量无定义输出不定值 B) 0 C) -1 #include main() { printf("%dn",NULL); } 答案: B 8.3 以下程序的输出结果是 A) 5,2,3 B) -5,-12,-7 C) -5,-12,-17 void sub(int x,int y,int *z) { *z=y-x; } main() { int a,b,c; sub(10,5,&a); sub(7,a,&b); sub(a,b,&c); printf("%d,%d,%dn",a,b,c); } 答案: B 8.4 以下程序的输出结果是 A) 4 B) 6 C) 8 D) 10 main() { int k=2,m=4,n=6; int *pb=&k,*pm=&m,*p; *(p=&n)=*pk*(*pm); D) *pb=*x D) 1 D) 5,-2,-7 printf("%dn",n); } 答案: C 8.5 已知指针p的指向如图8.5所示,则执行语句*p++; 后,*p的值是 A) 20 B) 30 C) 21 D) 31 答案: B 8.6 已知指针p的指向如图8.5所示,则表达式*++p的值是 A) 20 B) 30 C) 21 答案: B 8.7 已知指针p的指向如图8.5所示,则表达式++*p的值是 A) 20 B) 30 C) 21 答案: C 8.8 以下程序的输出结果是 A) 23 B) 24 C) 25 D) 26 void prtv(int *x) { printf("%dn",++*x); } main() { int a=25; prtv(&a); } 答案: D 8.9 以下程序的输出结果是 A) 运行出错 B) 100 C) a的地址 main() { int **k, *a b=100; a=&b; k=&a; printf("%dn",**k); } 答案: B 8.10 以下程序的输出结果是 A) 4,3 B) 2,3 C) 3,4 D) 3,2 void fun(float *a,float *b) { float w; *a=*a+*a; w=*a; *a=*b; D) 31 D) 31 D) b的地址 *b=w; } main() { float x=2.0,y=3.0; float *px=&x,*py=&y; fun(px,py); printf("%2.0f,%2.0fn",x,y); } 答案: C 8.11 以下程序的输出结果是 A) 9.000000 B) 1.500000 10.500000 void sub(float x,float *y,float *z) { *y=*y-1.0; *z=*z+x; } main() { float a=2.5,b=9.0,*pa,*pb; pa=&a,pb=&b; sub(b-a,pa,pa); printf("%fn",a); } 答案: C 8.12 以下四个程序中不能对两个整形值进行交换的是 A) main() { int a=10,b=20; swap(&a,&b); printf("%d%dn",a,b); } swap(int *p, int *q) { int *t,a; t=&a; *t=*p; *p=*q; *q=*t; } B) main() { int a=10,b=20; swap(&a,&b); printf("%d%dn",a,b); } swap(int *p, int *q) { int t; t=*p; *p=*q; *q=t; C) 8.000000 D) } C) main() { int *a,*b; *a=10,*b=20; swap(a,b); printf("%d%dn",*a,*b); } swap(int *p, int *q) { int t; t=*p; *p=*q; *q=t; } D) main() { int a=10,b=20; int *x=&a,*y=&b; swap(x,y); printf("%d%dn",a,b); } swap(int *p, int *q) { int t; t=*p; *p=*q; *q=st; } 答案:C 二、 填空题 8.13 以下程序段的输出结果是_____。 int *var,ab; ab=100; var=&ab; printf("%dn",*var); 答案:100 8.14 以下程序的输出结果是_____。 int ast(int x,int y,int *cp,int *dp) { *cp=x+y; *dp=x-y; } main() { int a,b,c,d; a=4; b=3; ast(a,b,&c,&d); printf("%d %dn",c,d); } 答案:7 1 8.15 若有定义:char ch; ab=*var+10; (1) 使指针p可以指向变量ch的定义语句是_____。 答案:char *p=&ch; (2) 使指针p可以指向变量ch的赋值语句是_____。 答案:p=&ch; (3) 通过指针p给变量ch读入字符scanf函数调用语句是_____。 答案:scanf("%c",*p); (4) 通过指针p给变量ch的赋字符的语句是_____。 答案:ch=*p; 5) 通过指针p输出ch中字符的语句是_____。 答案: printf("%c",*p); 8.16 若有如图8.5所示五个连续的int类型的存储单元并赋值如图,且p和s的基类型皆为int,p已指向存储单元a[1]。 (1) 通过指针p,给s赋值,使其指向最后一个存储单元a[4]的语句是____。 答案: s=p+3; (2) 用以移动指针s,使之指向中间的存储单元a[2]的表达式是____。 答案: s=s-2; (3) 已知k=2,指针s已指向存储单元a[2],表达式*(s+k)的值是____。 答案: 50 (4) 指针s已指向存储单元a[2],不移动指针s,通过s引用存储单元a[3]的表达式是____。 答案: *(a+1) 5) 指针s已指向存储单元a[2],p指向存储单元a[0],表达式s-p的值是____。 答案: 2 6) 若p指向存储单元a[0],则以下语句的输出结果是____。 for(i=0; i<5;i++) printf("%d ",*(p+i)); printf("n"); 答案:10 20 30 40 50 三、 编程题 8.17【分析与解答】 (1) 若函数名为fun,按题意,函数不返回函数值;函数的形参需要接受传送过来的两个浮点数,因此需要有两个double类型的形参;另外要把它们的和值与差值,通过形参传送回去,这就要求有两个double类型的形参指针,接受传送过来的地址,以便通过指针把和值与差值传送给所指的主函数中的变量。因此函数的首部应当是: void fun(double a, double b, double *p1, double *p2) 这里,a、b、p1、p2是自己取的名。 (2) 假设把a、b的和值传送给p1所指的存储单元,可用语句:*p1=a+b; 把a、b的差值传送给p2所指的存储单元,可用语句:*p2=a-b;。 (3) 因此函数可写成: void fun(double a,double b,double *p1,double *p2) { *p1=a+b; *p2=a-b; } (4) 在主函数中,若有定义语句:double x,y,z1,z2;,且x、y已赋值,则调用fun函数的语句可以是:fun(x,y,&z1,&z2);。 (5) 总结:本题所要求的算法极简单,但它要求有两个值返回,用return语句就不可能返回两个函数值。要求读者能利用形参指针把要求的值间接地传回调用函数。 8.18【参考答案】 (1) 若函数名为maxandmin,按题意,函数不返回函数值;函数将接受3个数(假定为int类型),并需要通过指针指向主函数中的两个int型变量,以便把最大值和最小值放入指针所指的存储单元中。因此函数的首部应当是: void maxandmin(int a,int b,int c,int *pmax,int *pmin) (2) 函数体中需要实现求3个数的最大值和最小值的算法,此算法应当在学习第四章时已经掌握(可参考例4.2和 习题4.24)。如果把a、b、c中的最大值暂时放在max中,把最小值放在min中,可用以下算法找到最大值: ① 假定a中的数最大,把a赋给max。 ② 用b去和max比较,若b大于max,则把b赋给max;若不大于max,则什么也不做。 ③ 用c去和max比较,若c大于max,则把c赋给max;若不大于max,则什么也不做。 ④ 经过以上操作,max中已放入了a、b、c三个数中的最大数。 ⑤ 可模仿以上算法找到最小值: min=a; if(b if(c (3) 若最大值已放入max中,最小值已放入min中,则可用以下语句把最大和最小值放入指针pmax和pmin所指的存储单元中: *pmax=max; *pmin=min; (4) 若主函数中已把3个数放入x、y、z中,要求把最大值放入m中,把最小值放在n中,则调用语句应当是: maxandmin(x,y,x,&m,&n); (5) 总结:本题要求的算法在第四章应当已掌握,本题的主要目的是要求读者掌握如何通过指针把函数中的多个结果传回主函数。 第九章 数组 一、 选择题 9.1 若已定义: int a[ ]={0,1,2,3,4,5,6,7,8,9},*p=a,i; 其中0≤i≤9,则对a数组元素的引用不正确的是 A)a[p-a] B)*(&a[i]) C)p[i] D)*(*(a+i)) 答案:D 9.2 以下程序段给数组所有元素输入数据,应在下划线处填入的是 A)a+(i++) B)&a(i+1) C)a+i D)&a[++i] main() { int a[10],i=0; while(i<10)scanf("%d",_________); . . . } 答案:D 9.3 以下程序的输出结果是 A)3 B)4 C)1 D)2 main() { int a[10]={1,2,3,4,5,6,7,8,9,10},*p=a; printf("%dn",*(p+2)); } 答案:A 9.4、 以下程序的输出结果是 A)不确定的值 B)3 C)2 D)1 main() { int n[2]={0},i,j,k=2; for(i=0;i for(j=0;j printf("%dn",n[k]); } 答案: A 9.5 以下程序的输出结果是 A)17 B)18 C)19 D)20 main() { int a[ ]={2,4,6,8,10},y=1,x,*p; p=&a[1]; for(x=0;x<3;x++) y+=*(p+x); printf("%dn",y); } 答案: C 9.6 以下程序的输出结果是 A)6 B)8 C)4 D)2 main() { int a[10]={2,4,6,8},*p=a,i; for(i=0;i<4;i++)a[i]=*p++; printf("%dn",a[2]); } 答案:A 9.7 以下程序的输出结果是 A)720 B)120 C)24 D)6 f(int b[ ],int n) { int i,r=1; for(i=0;i<=n;i++)r=r*b[i]; return r; } main() { int x,a[]={2,3,4,5,6,7,8,9}; x=f(a,3); printf("%dn",x); } 答案:B 9.8 以下程序中若第一个printf语句输出的是194,则第二个printf语句的输出结果是 A)212 B)204 C)1a4 D)1a6 main() { int a[]={1,2,3,4,5,6,7,8,9,0},*p; p=a; printf("%xn",p); printf("%xn",p+9); } 答案:D 9.9 以下程序的输出结果是 A) B)4321098765 C)5678901234 D) fun(int *s,int n1,int n2) { int i,j,t; i=n1; j=n2; while(i { t=*(s+i); *(s+i)=*(s+j); *(s+j)=t; i++; j--; } } main() { int a[10]={1,2,3,4,5,6,7,8,9,0},*p=a,i; fun(p,0,3); fun(p,4,9); fun(p,0,9); for(i=0;i<10;i++)printf("%d",*(a+i)); } 答案: C 9.10 以下程序的输出结果是 A) 4 4 B) 2 2 C) 2 4 D) 4 6 main() { int a[5]={2,4,6,8,10},*p,**k; p=a; k=&p; printf("%d ",*(p++)); printf("%dn",**k); } 答案: C 9.11 当运行以下程序时输入三行,每行都是在第一列上开始, a b cdef 则程序的输出结果是 A) abcdef B) a C) a D) a b b b c cd cdef d e f #include "stdio.h" #define N 6 main() { char c[N]; int i=0; for(i=0;i for(i=0;i } 答案: C 9.12 若有定义和语句: int c[4][5], (*cp)[5]; cp=c; 则对c数组元素的引用正确的是 A) cp+1 B) *(cp+3) C) *(cp+1)+3 D) *(cp+2) 答案: D 9.13 若已定义: int a[4][3]={1,2,3,4,5,6,7,8,9,10,11,12},(*prt)[3]=a,*p=a[0]; 则能正确表示数组元素a[1][2]的表达式是 A) *((*prt+1)[2] B) *(*(p+5)) C) (*prt+1)+2 D) *(*(a+1)+2) 答案: D 9.14 若有定义和语句: int a[4][3]={1,2,3,4,5,6,7,8,9,10,11,12},(*prt)[3]=a,*p[4],i; for(i=0;i<4;i++) p[i]=a[i]; 则不能够正确表示a数组元素的表达式是 A) a[4][3] B) p[0][0] C) prt[2][2] D) (*(p+1))[1] 答案: A 9.15 以下程序的输出结果是 A) 23 B) 26 C) 33 D) 36 main() { int aa[3][3]={{2},{4},{6}},i,*p=&aa[0][0]; for(i=0; i<2; i++) { if(i==0) aa[i][i+1]=*p+1; else ++p; printf("%d",*p); } printf("n"); } 答案: A 9.16 以下程序的输出结果是 A) 60 B) 68 C) 99 D) 108 main() { int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int (*p)[4]=a,i,j,k=0; for(i=0; i<3; i++) for(j=0; j<2; j++) k+=*(*(p+i)+j); printf("%dn",k); } 答案: A 9.17 以下程序的输出结果是 A) 1,5,9, B) 1,4,7, C) 3,5,7, D) 3,6,9, main() { int i,x[3][3]={1,2,3,4,5,6,7,8,9}; for(i=0; i<3; i++) printf("%d,",x[i][2-i]); } 答案: C 9.18 若有定义语句 int (*p)[M]; 其中的标识符p是 A) M个指向整型变量的指针 B) 指向M个整型变量的函数指针 C) 一个指向具有M个整型元素的一维数组指针 D) 具有M个指针元素的一维指针数组,每个元素都只能指向整型量 答案: C 二、填空题 9.19 若有以下定义: double w[10]; 则w数组元素下标的上限是____,下限是____。 答案: 9 0 9.20 以下程序的输出结果是____。 main() { int a[]={2,4,6},*prt=&a[0],x=8,y,z; for(y=0; y<3; y++) z=(*(prt+y) printf("%dn",z); } 答案:6 9.21 以下程序的输出结果是____。 main() { int arr[10],i,k=0; for(i=0; i<10; i++) arr[i]=i; for(i=0; i<4; i++) k+=arr[i]+i; printf("%dn",k); } 答案:12 9.22 以下程序的输出结果是____。 #define N 5 fun(char *s,char a,int n) { int j; *s=a; j=n; while(a return j; } main() { char s[N+1]; int k,p; for(k=1; k<=N; k++) s[k]=''''A''''+k+1; printf("%dn",fun(s,''''E'''',N)); } 答案:3 9.23 若输入3个整数3,2,1,则以下程序的输出结果是____. void sub(int n,int uu[]) { int t; t=uu[n--]; t+=3*uu[n]; n++; if(t>=10) { uu[n++]=t/10; uu[n]=t%10; } else uu[n]=t; } main() { int i,n,aa[10]={0}; scanf("%d%d%d",&n,&aa[0],&aa[1]); for(i=1; i for(i=0; i<=n; i++) printf("%d",aa[i]); printf("n"); } 答案: 2721 9.24 以下程序的输出结果是____. main() { int i,j,row,col,m; int arr[3][3]={{100,200,300},{28,72,-30},{-850,2,6}}; m=arr[0][0]; for(i=0; i<3; i++) for(j=0; j<3; j++) if(arr[i][j] { m=arr[i][j]; row=i; col=j; } printf("%d,%d,%dn",m,row,col); } 答案: -850,2,0 9.25 以下findmax返回数组s中最大元素的下标,数组中元素的个数由t传入,请填空。 findmax(int s[],int t) { int k,p; for(p=0,k=p; p if(s[p]>s[k]) ____; return ____; } 答案: k=p k 9.26 以下程序统计从终端输入的字符中每个大写字母的个数,num[0]中统计字母A的个数, 其它依次类推.用#号结束输入,请填空. #include "stdio.h" #include "ctype.h" main() { int num[26]={0},i; char c; while(____!=''''#'''') if(isupper(c)) num[___]+=1; for(i=0; i<26; i++) if(num[i]) printf("%c: %dn",i+''''A'''',num[i]); } 答案: (c=getchar()) c-''''A''' 三、 上机题 9.27【分析与解答】 (1) 对于字符的输入可参考教材例6.3和习题9.26中的while循环,只是要注意,循环的终止条件是:等于′\[KG-*3]n′。 (2) 在while循环体中,用if条件来判断是否为数字字符,若是,就使对应的元素增1;if中的条件表达式可用C的库函数:isdigit(ch),这时要在程序前加:#i nclude (3) 若用num数组元素来进行统计,当ch中是数字“0”时,使num[0]增1、当ch中是数字 “1”时,使num[1]增1……num的下标表达式可用:ch-′0′。 (4) 注意,在定义数组时,数组的大小应符合使用的要求。在利用数组元素作为计数器时,不要忘记首先应该给数组元素赋0值。 (5) 总结:通过本题的编程,要求掌握利用数组元素作为计数器的基本算法。 9.28【分析与解答】 本题的编程请参考例9.8。 (1) 若有以下10个整数: 0 1 2 3 4 5 6 7 8 9 要求从第5个元素依次向前移,则移动之后的数列应该是: 0 1 2 4 5 6 7 8 9 第5个元素不是指下标为5的元素,而是指排列的顺序,对此数列而言是指数值为4的那个。 (2) 完成移动后,数列中的数据个数减1。 (3) 若进行指定操作的函数名为moves,则函数的首部可如下: void moves(int *a,int n,int *m) 这里a用以指向一维数组的首地址,n接受开始移动的元素的位置,m指向主函数中存放元素个数的变量,因为没有函数值返回,因此函数的类型定义为void。 (4) 可用以下for循环完成指定的移动: for(i=n-1;i<*m;i[KG-*3]+[KG-*3]+) a[i-1]=a[i]; 注意,应当先把第n个元素(下标为n-1)移到第n-1个元素(下标为n-2)的位置上,依次葱馨到后向前移动。 (5) 完成移动之后,应使m所指变量中的值减1,表示数列中的数据少了一个;这可由于句: *m=*m-1;来完成。 (6) 可设计一个输出函数,在移动前、后调用此函数输出数组中的数据,以便验证操作是否正确。若输出函数名为:outarr,则函数首部可写成: void outarr( int a[], int num) 形参a指向待输出的数组,num接受数组中元素的个数。输出操作可由一个for循环来完成:
版权声明:本文标题:《全国计算机等级考试二级教程C语言程序设计》 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1704335186h455261.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论