全国计算机等级考试教程二级C语言答案 daan3
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《全国计算机等级考试二级教程——C语言程序设计》习题分析与解答(三)
第六章字符型数据习题分析与解答
一、选择题
6.1【参考答案】 B)
6.2【参考答案】 D)
6.3【参考答案】 A)
6.4【参考答案】 A)
6.5【参考答案】 B)
6.6【参考答案】 D)
6.7【参考答案】 D)
6.8【参考答案】 B)
6.9【参考答案】 A)
6.10【参考答案】 A)
6.11【参考答案】 C)
二、填空题
6.12【参考答案】 -1
6.13【参考答案】 1
6.14【参考答案】 ctype.h
6.15【参考答案】 0
6.16【参考答案】 10A 20B 30C 40D<CR>
或: 10A<CR>
20B<CR>
30C<CR>
40D<CR>
6.17【参考答案】
7.29 101.298AB<CR>
或: 7.29<CR>
101.29AB<CR>
6.18【参考答案】
三、编程题
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 【参考答案】 C)
7.2 【参考答案】 C)
7.3 【参考答案】 B)
7.4【参考答案】 C)
7.5【参考答案】 A)
7.6【参考答案】 D)
7.7【参考答案】 A)
二、填空题
7.8【参考答案】 12
7.9【参考答案】 9.0(或9.000000)
7.10【参考答案】 4
7.11【参考答案】[1] n=1 [2] s
7.12【参考答案】[1] <=y [2] z*x
7.13【参考答案】[1] 1 [2] s*i [3] 0 [4] 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 2,k的值逐项增1,由2变化到m。
因此,算法可以用一个循环来实现。
(3) 当m的值为12时,函数值应是:0.435023。
7.18【分析与解答】
(1) 若函数取名为fun,按题意,x作为形参,由调用函数传入,其类型不应当用整型;表达式x 2-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,因此应当在程序的最前面包含以下命令行:
#include ″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【参考答案】 A)
8.2【参考答案】 B)
8.3【参考答案】 B)
8.4【参考答案】 C)
8.5【参考答案】 B)
8.6【参考答案】 B)
8.7【参考答案】 C)
8.8【参考答案】 D)
8.9 【参考答案】 B)
8.10【参考答案】 C)
8.11【参考答案】 C)
8.12【参考答案】 C)
二、填空题
8.13【参考答案】 110
8.14【参考答案】 7 1
8.15【参考答案】
8.16【参考答案】
三、编程题
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<min)min=b;
if(c<min)min=c;
(3) 若最大值已放入max中,最小值已放入min中,则可用以下语句把最大和最小值放入指针pmax和pmin所指的存储单元中: *pmax=max; *pmin=min;
(4) 若主函数中已把3个数放入x、y、z中,要求把最大值放入m中,把最小值放在n中,则调用语句应当是:
maxandmin(x,y,x,&m,&n);
(5) 总结:本题要求的算法在第四章应当已掌握,本题的主要目的是要求读者掌握如何通过指针把函数中的多个结果传回主函数。