《浙工大C语言课本习题答案》 下载本文

C程序设计习题参考答案

习 题 一 ................................................................................................. 2 习 题 二 ................................................................................................. 3 习 题 三 ................................................................................................. 5 习 题 四 ................................................................................................. 8 习 题 五 ............................................................................................... 14 习 题 六 ............................................................................................... 17 习 题 七 ............................................................................................... 20 习 题 八 ............................................................................................... 26 习 题 九 ............................................................................................... 33 习 题 十 ............................................................................................... 35 习 题 十一 .......................................................................................... 36

1

习 题 一

1. 填空题

⑴ 计算机程序设计语言按其发展可分为三类,即 机器语言 、汇编语言和 高级语言 。 ⑵ C程序是由 函数 构成的,一个C程序中至少包含 1个main函数。因此, 函数是C程序的基本单位。

⑶ C程序注释是由 /* 和 */ 所界定的文字信息组成的。 ⑷ 函数体一般包括 函数首行 和 函数体 。

⑸ 在任何C程序中都必须且只能有一个主函数, 主函数名必须为 main 。 2. 判断下列各个叙述的正确与否

⑴ C程序的执行总是从该程序的main函数开始,在main函数最后结束【√】 ⑵ C程序的注释部分可以出现在程序中任何位置,它对程序的编译和运行不起任何作用,但可以增加程序的可读性【√】

⑶ 由“/*”与“*/”界定的注释必须在同一行【╳】 ⑷ 通过了编译、连接的程序就是正确的程序【╳】 ⑸ 有计算结果输出的程序一定是正确的程序【╳】 ⑹ 编译错误是语法错误,运行结果错误是逻辑错误【√】

⑺ 编译时在信息窗口出现包含“error”的信息,说明程序存在警告性错误【╳】 ⑻ 源程序每次修改后,都必须重新编译、连接【√】 3. 简答题

⑴ 算法的含义、特点是什么?

解答:算法是解题方法的精确描述。有穷性、确定性、有多或零个输入、有1或多个输出、有效性。

⑵ 写出一个C程序的基本结构。

由编译预处理命令、注释、1个main和若干个自定义函数构成,函数格式如下: 函数类型 函数名(类型标识符 形参,类型标识符 形参,...) { 类型声明语句; 执行语句部分; }

⑶ 写出在你使用的计算机系统上,进入C环境以及运行、调试程序的简要步骤。 ⑷ 输入x后计算其正弦值的源程序如下。编译信息是否表示有致命性错误?应如何修改?

解答:致命性错误为第6行函数sin未声明,应加入编译预处理命令 #include 4. 编程题

⑴ 请上机调试、运行本章课本上C语言程序例题4~6(注释部分可以不必输)

2

⑵ 仿照例6编程,输入两个变量后,输出其中较大的值。 #include void main() { int a, b;

printf(\请输入A,B的值:\\n\ scanf(\

if(a>b) printf(\ }

⑶ 仿照例题编程,输入圆柱体的半径和高,计算并输出圆柱体的体积。 #include void main()

{ float r, h, v;

printf(\请输入半径、高的值:\\n\ scanf(\ v=r*r*3.141593*h; printf(\ }

习 题 二

1. 将下列程序上机运行,写出你所使用的C语言处理系统中short、int以及long类型数据的字长和数值范围。

#include void main()

{ printf(\类型数据的字长为:%d\\n\ printf(\类型数据的字长为:%d\\n\ printf(\类型数据的字长为:%d\\n\ }

解答:VC++环境下,分别为2、4、4

2. 仿照题1编程,测试float、double类型数据的字长。 #include void main()

{ printf(\类型数据的字长为:%d\\n\ printf(\类型数据的字长为:%d\\n\ }

3. 判断下列各个叙述的正确与否。

⑴ C的long类型数据可以表示任何整数【╳】 ⑵ 任何变量都必须要声明其类型【√】

⑶ C的任何类型数据在计算机内都是以二进制形式存储的【√】 ⑷ scanf函数中的格式符“%d”不能用于输入实型数据【√】

⑸ 格式符中指定宽度时,从缓冲区中读入的字符数完全取决于所指定的宽度【√】 ⑹ 按格式符“%d”输出float类型变量时,截断小数位取整后输出【╳】 ⑺ 按格式符“%6.3f”输出i(i=123.45)时,输出结果为 23.450【╳】

3

⑻ scanf函数中的格式符“%f”能用于输入double类型数据【╳】 4. 指出下列各项中那些是C的常量,对合法的C常量请同时指出其类型。 10,150 007 -0x3d π 1e0 e1 o7o8 'x' 'xo' 1.52e0.5 sin(3) 0xf16 \1.414E+2 2.54 '\\\\' 'a'

解:007整型,-0x3d整型,1e0实型,'x'字符型,0xf16整型,\字符串 '\\007'字符型,1.414E+2实型,2.54实型,'\\\\'字符型,'a'字符型 5. 指出下列各项中那些是C的标识符(可作变量名)。

x_1 X_2 High printf β 3DS i/j e2 -e2 count Int number $23 next_ 解:x_1、X_2、High、e2、count、Int、number、next_ 6. 根据条件,写出下列各题的输出结果。

⑴ int i=234,j=567; 函数printf(\的输出结果是 234567 。 ⑵ int i=234; float x=-513.624;

函数printf(\的输出结果是 i= 234 x=-513.6240 。 ⑶

float

alfa=60,pi=3.1415926535626;

printf(\

的输出结果是 sin( 60*3.141592/180) 。 ⑷ char ch='$',float x=153.45;

函数printf(\的输出结果是 $153.45 \\n 。 ⑸ int d=27; 函数27 ,34 ,1b。

float

x1=13.24,x2=-78.32;

printf(\

x(%d)=%.2f\\n\

的输出结果是 x(1)=13.24 x(2)=-78.32

7. 根据下列条件写出变量i1(int类型)、c1(char类型)、f1(float类型)、d1(double类型)的当前值。

⑴ 执行scanf(\时输入52$9.17 3.1415926535 后。 i1为52,c1为'$',f1为9.17,d1为3.1415926535

⑵ 执行scanf(\时输入52$9.17 3.1415926535 后。 i1为52,c1为'9',f1为0.17,d1为3.1415926535

8.下列源程序输入x、y后,输出x的y次方。运行时无编译、连接错误,但输入不同格式的两组数据输出结果却不同,哪一组是对的?请说明原因。

解答:第1组输入数据错误,因为格式串中有“,”所以键盘输入数据x、y之间也一定以逗号为间隔符。

printf(\的输出结果是

4

9. 写出下列程序运行时输入 3 4 5 的输出结果。 #include #include 输出结果:边长为3.00,4.00,5.00的三角形面积为6.00 void main()

{ float a1,a2,a3,s,d;

scanf(\ s=(a1+a2+a3)/2;

s=sqrt(s*(s-a1)*(s-a2)*(s-a3));

printf(\边长为%.2f,%.2f,%.2f的三角形面积为:%-10.3f\\n\ } 10. 编程题

⑴ 编程,用getchar函数接收2个字符,用putchar函数输出这2个字符。 解答: #include void main() { char x;

x=getchar(); putchar(x); x=getchar(); putchar(x); }

⑵ 编程,用scanf函数输入1个10进制整数、1个单精度浮点数、1个双精度浮点数,并通过printf函数把输入的3个数分别输出。

解答: #include void main()

{ int k; float x; double d; scanf(\ printf(\ }

⑶ 编程,输入1个整数,然后分别以8进制、10进制、16进制形式输出该数。 解答: #include void main()

{ int x; scanf(\

printf(\ }

习 题 三

1. 根据下列数学式,写出C的算术表达式。

?(a2?b)?y342?10tan?125?ba?6b?5?c?d5

x??

解答:-(a*a+pow(b,3))*pow(y,4) (sqrt(2)+100)/(atan(x)+3.141593) (5+b)/((a+6)/(b+5)-c*d) 2. 按照要求写出下列C的表达式。

⑴ 数学式 (x+1)e所对应的C算术表达式。

⑵ 将double类型变量x的整数部分与y的小数部分相加的算术表达式。 ⑶ 将非零实型变量x四舍五入到小数点后2位的算术表达式。 ⑷ 为变量s赋值:取变量x 的符号,取变量y的绝对值。 ⑸ 条件“-5≤x≤3”所对应的C逻辑表达式。

⑹ a、b是字符变量,已知a的值为大写字母、b的值为小写字母,写出判断a、b是否为同一字母的逻辑表达式

⑺ int类型变量a、b均为两位正整数,写出判断a的个位数等于b的十位数、且b的个位数等于a的十位数的逻辑表达式。

⑻ 计算变量a、b中较小值的条件表达式。 ⑼ 判断变量ch 是英文字母的表达式;

⑽ 若字符变量ch的值为大写字母,则重新赋值为对应的小写字母。 解答: ⑴

(x+1)*exp(2*x)

(int)x+y-(int)y

(int)(x*100+fabs(x)/x*0.5)/100.0

⑷ s= fabs(y)*x/fabs(x) ⑸ -5<=x && x<=3 ⑹ b-a=='a'-'A' ⑺ a==b/10 && b==a/10 ⑻ a

3. 声明“int k=12;float x=9.5;double d=2.7;char zf='B';”,写出下列表达式值。 ⑴ (int)x%k*d ⑵ k+5.6d ⑸ zf='B' ⑹ zf=='B' 解答:⑴ 24.3,⑵ 1,⑶ 1,⑷ 0,⑸ 'B',⑹ 1 4. 填空题

⑴ 声明“float x=2.5,y=4.7; int a=7;”,表达式x+a%3*(int)(x+y)%2/4值为 2.5 。 ⑵ 设整型变量a、b值分别为10与20,计算c=(a%2==0)?a:b后,c的值为 10 。 ⑶ 设整型变量d的值为7,表达式“3='A' && ch<='z' )ch=ch-32;

⑸ 下列程序的输出结果是 (0.00,0.5) 。 #include void main( ) { int y;

double d=3.4, x; x=(y=d/2.0)/2;

printf(\ }

⑹ 判断a、b是否绝对值相等而符号相反的逻辑表达式为 a==-b 。

⑺ 判断变量a、b中必有且只有一个为0的逻辑表达式为 a*b==0 && a+b!=0 。 ⑻ c初值为3,计算赋值表达式“a=5+(c+=6)”后表达式值、a、c的值依次为 14、14、

2X

6

9 。

⑼ 求解赋值表达式“a=(b=10)%(c=6)”后,表达式值、a、b、c的值依次为 4、4、10、6。

⑽ 求解逗号表达式“x=a=3,6*a”后,表达式值、x、a的值依次为 18、18、3 。 ⑾ 若a=13、b=25、c=-17,表达式“((y=(a='a'&&s<='z')?s-32:s;”后字符变量s的值为 'D' 。 5. 写出下列程序的输出结果。 程序 ⑴ #include void main()

{ unsigned k,n; scanf(\ k=n*10+n/10;

printf(\ }

运行时输入数据为:69 72 输出结果为: n=69 k=96 程序 ⑵ #include void main()

{ int x=40,y=4,z=4;

x=y==z; printf(\ x=x==(y=z); printf(\ }

输出结果为: 1 4 4 0 4 4

程序 ⑶ #include void main() { int x,y,z; x=y=2; z=3;

y=x++-1; printf(\ y=--z+1; printf(\ x=y=z=0; ++x&&++y||++z;

printf(\

--x&&++y&&++z; printf(\ }

输出结果为: 3 1 3 3 3 2 1 1 0 0 1 0

6. 编程,输入长方形的长和宽,求长方形的面积和周长并输出。 解答: #include void main()

{ float a,b,x,y;

scanf(\ printf(\面积=%.4f 周长=%.4f\\n\ }

7. 编程,输入3个字符后,按各字符ASCII码从小到大的顺序输出这些字符。 解答: #include

7

void main()

{ char a,b,c,x,y,z; scanf(\

x=(x=ab?a:b)>c?z:c; y=a+b+c-x-z; printf(\ }

8. 编程,输入3个整数,要求按绝对值从小到大输出它们的值。 解答: #include

#include //也可以用题7的做法 void main()

{ int x,y,z,a; scanf(\ if(fabs(x)>fabs(y)) { a=x;x=y;y=a;} if(fabs(x)>fabs(z)) { a=x;x=z;z=a;} if(fabs(y)>fabs(z)) { a=y;y=z;z=a;} printf(\ }

9. 编程,输入3个数,计算这三个数的平均值,并求出与平均值最接近的值。 解答: #include #include void main()

{ float a,b,c,v,x; scanf(\ v=(a+b+c)/3; x=a;

if(fabs(b-v)

10. 编程,输入1个3位正整数,输出其个位、十位、百位反序的数(如123反序数为321)。

解答: #include void main()

{ int n,m; scanf(\

m=n*100+n0/10*10+n/100; printf(\ }

习 题 四

1. 填空题

⑴ 求1至100的和,写作 for(s=0,i=1; i<=100 ;++i) s+=i; ⑵ 执行程序段“y=1;x=5; while(x--); y++;”后,y的值为 2 。 ⑶ 顺序输出26个大写英文字母的循环结构,写作 for( ch='A';ch<='Z';ch++ ) putchar(ch);

⑷ 输入若干个以问号结束的字符,同时输出这串字符(不包括问号),写作 while( (ch=getchar()) !='?') putchar(ch);

8

⑸ 循环程序段“k=5; for(;k<0;k--);”执行后,k的值为 5 。 2. 改写下列程序段,去掉continue语句,使结构更为合理。 ⑴ while(A) { 解答: while(A) if(!B) C; if(B) continue; C; }

⑵ do { 解答: while(A) { B; C;} if(!A) continue; else B; C; } while(A);

3. 写出下列程序的输出结果 程序⑴ #include void main()

{ char x; int n=0,k=0;

while((x=getchar())!='.') { switch(x) {

case 't': k++; break;

case 'h': if(k==1) k++; break; case 'e': if(k==2) k++; break; default: k=0; }

if(k==3) n++; }

printf(\ }

运行时输入:a the asdftheth e there. 输出结果: 3 程序⑵ #include 输出结果: A #include BBB void main() CCCCC { char a,b,x; int i; DDDDDDD while(!isupper(x=getchar())); EEEEEEEEE for(a='A';a<=x;a++) {

for(b='A';b<'A'+x-a;b++) putchar(' '); for(i=1;i<=2*(a-'A')+1;i++) putchar(a); putchar('\\n') } }

运行时输入:35dffE

4. 程序填空题,根据下列各题题意,将程序补充完整。

⑴ 下列程序在输入m后求n使 n!≤m≤(n+1)!(例如输入726,应输出n=6) #include void main()

{ int m,n,jc=1 ;

9

scanf( \

for(n=2;jc<=m;n++) jc=jc*n; printf(\ }

⑵ 下列程序输出6至10000之间的亲密数对。

【说明】若a、b是亲密数对,则a的因子和等于b、b的因子和等于a且a不等于b。 #include void main() { int a,b,c,i;

for(a=6;a<=10000;a++) {

b=1; for(i=2;i<=a/2;i++) if( a%i==0 ) b+=i; c=1 ; for(i=2;i<=b/2;i++) if(b%i==0) c+=i; if( c==a &&a!=b) printf(\ } }

5.根据下列各小题题意编程。

⑴ 编程,输入x后按下式计算y值并输出。

解答: #include #include void main()

{ float x,y; scanf(\

if(x>=0 && x<=1) y=x+sin(x); else y=x+sin(x); printf(\ }

⑵ 输入一个百分制的成绩t后,按下式输出它的等级,要求分别写作if结构和switch结构。等级为:90~100为A,80~89为B,70~79为C,60~69为D,0~59为E。 解答: #include void main()

{ int t; char x; scanf(\

if(t>=90) x='A'; switch((int)t/10) {

else if(t>=80) x='B'; case 9: case 10: x='A'; break; else if(t>=70) x='C'; case 8: x='B'; break; else if(t>=60) x='D'; case 7: x='C'; break; else x='E'; case 6: x='D'; break; printf(\ } } ⑶ 输入10个学生的成绩,输出最低分数和最高分数。 解答: #include void main()

{ int x,max=0,min=101,i;

10

for(i=1;i<=10;i++) {

scanf(\ if(x

printf(\ }

⑷ 按公式 1+1/1!+1/2!+1/3!+...+1/n!+... 计算e的值,要求误差小于给定的ε。 解答: #include void main()

{ float s=2,eps,t=1; int i=2; scanf(\

while(t>=eps) { t/=i++; s+=t; } printf(\ }

⑸ 统计输入的若干个数中负数、零及正数的个数(输入^z控制循环结束)。 解答: #include void main()

{ float x; int zs=0,lin=0,fs=0; while(scanf(\

if(x>0) zs++; else if(x<0) fs++; else lin++;

printf(\正数%d个,零%d个,负数%d个\\n\ }

⑹ 输入k,利用下列迭代公式计算k的近似值,要求计算结果具14位有效位数。

2xn?1?xn?(k/xn?xn)/3 解答: #include #include void main()

{ int k; double x,x0; scanf(\ while(1) {

x0=x; x=x0+(k/(x0*x0)-x0)/3;

if(fabs(x-x0)<1e-14) { printf(\ } }

⑺ 编程,输入n后,计算下列表达式的值。

1?2?3?4?...n?1?n1/3

解答: #include #include void main()

{ int i,n; float y=0; scanf(\

for(i=n;i>=1;i--) y=sqrt(i+y); printf(\

11

}

⑻ 编程,输入x、n后,计算下列表达式的值。

a0?a1x?a2x23n?a3x???anx

解答: #include void main()

{ float x,y,a; int i,n; scanf(\

for(i=0; i<=n; i++) { scanf(\ printf(\ }

⑼ 当x为-2、-1.5、...、1.5、2时,求f(x)=x-3.14·x-6所取最大值、最小值。 解答: #include void main()

{ float x,y,max,min;

x=-2; max=min=x*x-3.14159*x-6; for(x=-1.5; x<=2; x=x+0.5) { y=x*x-3.14159*x-6;

if(y>max) max=y; else if(y

printf(\ }

⑽ 编程,输入两个正整数x和y,求它们的最大公约数和最小公倍数。 解答: #include void main() { int x,y,a;

scanf(\ while(a%y!=0) a+=x;

printf(\最小公倍数%d,最大公约数%d\\n\ }

⑾ 编程,输出1~5000之间的同构数(就是出现在其平方数右边的那些数,如 5、6、25均为同构数)。

解答: #include #include void main() { int k,kk,n;

for(k=1;k<=5000;k++) { n=log10(k)+1;

if((k*k-k)%(int)pow(10,n)==0) printf(\ } }

⑿ 参照例25编程,输出下列形式的九九乘法表。

2

12

解答: #include void main() { int i,j;

printf(\ putchar('\\n');

for(i=1;i<10;i++) { printf(\ for(j=1;j<10;j++) printf(\ putchar('\\n'); } }

⒀ 当n取值在-39~40范围内时,判断表达式 n2

+n+41 的值是否都是素数。 解答: #include #include void main() { int i,j,y;

for(i=-39;i<=40;i++) { y=i*i+i+41;

for(j=3;j<=sqrt(y);j+=2) if(y%j==0) break;

if(j<=sqrt(y)) printf(\结论不成立!\\n\printf(\

} }

⒁ 参照例24题编程,用梯形公式求下列定积分。

?31?x3dx

1解答: #include #include void main()

{ float a,b,h,s; int i,n; scanf(\ h=(b-a)/n; x=a;

s=0.5*(sqrt(1+a*a*a)+sqrt(1+b*b*b));

for(i=1;i

else

13

}

⒂ 用区间对分法求 x+x·sinx-5=0 在区间[0,5]内的一个实根(设ε=10)。 【说明】在[a,b]区间连续的函数f(x),若满足条件f(a)·f(b)<0,则必有a<ξ

-5

得f(ξ)=0。求f(x)=0在[a,b]内一个实根的区间对分法基本步骤如下:

① c←(a+b)/2;

② |f(c)|<ε或 |b-a|<ε则输出c作为近似解并终止程序执行; ③ 如果f(a)·f(c)<0则 b←c 否则 a←c,再次执行第⑴步。

解答: #include #include void main()

{ float a,b,c; a=0; b=5; do {

c=(a+b)/2;

if((a*a+a*sin(a)-5)*(c*c+c*sin(c)-5)<0 ) b=c; else a=c; } while(fabs(c*c+c*sin(c)-5)>=1e-5 && fabs(b-a)>=1e-5); printf(\ }

习 题 五

1.判断下列各个叙述的正确与否。

⑴ 函数的类型标识符缺省类型为void【√】 ⑵ 函数中不可以没有return语句【╳】

⑶ 传值调用的形参只有在被调用时才被创建(分配存储单元)【√】 ⑷ 传值调用时,实参不限于变量名,而可以是表达式【√】 ⑸ 被定义为前向调用的函数,不必再声明其函数原型【√】 ⑹ 函数f可以用f(f(x))形式调用,f是递归函数【╳】

2.写出下列程序的输出结果。

程序⑴ #include

void prn(int a,int b,int c,int max,int min) { max=(max=a>b?a:b)>c?max:c; min=(min=a

printf(\ }

void main() { int x,y;

x=y=0; prn(19,23,-4,x,y);

printf(\ }

输出结果为 max=23 min=-4 max=0 min=0

程序⑵ #include int f(int m,int n)

14

{ if(m%n==0) return n; else return f(n,m%n); }

void main()

{ printf(\ 输出结果为 24

程序⑶ #include

int f1(int,int),f11(int); void f2(int); void main() { int i,j;

for(i=0;i<5;i++) {

f2((5-i)*3); for(j=0;j<=i;j++) printf(\ putchar('\\n'); } }

int f1(int m,int n)

{ return f11(m)/f11(n)/f11(m-n); } int f11(int k)

{ if(k<=1) return 1; return k*f11(k-1); } void f2(int n)

{ for(int i=1;i<=n;i++) putchar(' '); } 输出结果为 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1

3.根据下列各题题意填空,将程序补充完整。

⑴ 输入若干个正整数,判断每个数从高位到低位各位数字是否按值从小到大排列。 #include int fun1(int);

void main() { int n;

while(scanf(\

if(fun1(n)) printf(\中各位数字按从小到大排列\\n\ }

int fun1( int m ) { int k; k=m; while(m)

if( m/10>k) return 0; else { m=m/10 ; k=m; } return 1; }

15

⑵ 函数f10_2可以显示形参变量所对应的二进制形式。下列程序的两行显示结果分别为“1011”、“100011”。

#include void f10_2(int n)

{ if( n==0 ) return; else {

f10_2( n/2 ); printf(\ } }

void main()

{ f10_2(11);putchar('\\n'); f10_2(35);putchar('\\n'); }

4.根据下列各小题题意编程。

⑴ 编制函数,返回三个变量中的最大值。 解答: float f(float a,float b,float c) { float max;

max=(max=a>b?a:b)>c?max:c; return max; }

⑵ 编制函数,判断一个整数a是否是区间[1,b]之间的素数。 解答: int f(int a,int b) { int i;

if(a>b||a<2) return 0;

for(i=2; i<=sqrt(a); i++) if(a%i==0) return 0; return 1; }

⑶ 编写函数,其返回值为整数n从右边开始的第k位数字的值。如digit(231456,3)返回4,digit(1456,5)返回0。

解答: int f(int n,int k) { int i;

for(i=1;i

⑷ 输出1~1000之间的所有完数。要求自定义一个函数,功能是判断某个正整数是否为完数,如果是完数,函数返回值为1,否则为0(一个数的所有因子之和等于该本身,该数就是完数。如6、28都是完数;6=1+2+3;28=1+2+4+7+14)。

解答: #include int f(int n) { int i,y=1;

for(i=2;i<=n/2;i++) if(n%i==0) y=y+i; if(y==n) return 1; else return 0; }

16

void main(} { int i;

for(i=1;i<=1000;i++) if(f(i)) printf(\ }

⑸ 定义函数,形参为两个int类型变量,功能是显示这两个数的最大公约数和最小公倍数。

解答: void f(int x,int y) { int a=x;

while(a%y!=0) a+=x;

printf(\最小公倍数%d,最大公约数%d\\n\ }

⑹ 多项式p(n,x)定义如下,编写递归函数求该多项式的值。

解答: double p(int n,double x) { if(n==0) return 1;

else if(n==1) return x;

else return((2*n-1)*x*p(n-1,x)-(n-1)*p(n-2,x))/n; }

习 题 六

1. 单项选择题

⑴ 程序中调用了库函数exit,必须包含头文件【D】

A、math.h B、string.h C、ctype.h D、stdlib.h ⑵ 程序中调用了库函数strcmp,必须包含头文件【B】

A、math.h B、string.h C、ctype.h D、stdlib.h ⑶ 下列宏定义命令中,哪一个格式是正确的【C】

A、#define pi=3.14159; B、define pi=3.14159 C、#define pi 3.14159 D、#define pi(3.14159); ⑷ 定义带参数的宏计算两个表达式的乘积,下列定义中正确的是【C】 A、#define muit(u,v) u*v B、#define muit(u,v) u*v; C、#define muit(u,v) (u)*(v) D、#define muit(u,v)=(u)*(v) ⑸ 宏定义为“#define div(a,b) a/b”,对语句

“printf(\”作宏替换后为【A】 A、printf(\、printf(\ C

printf(\

D

printf(\

2. 填空题

⑴ 定义一个带参数的宏,若变量中的字符为大写字母则转换成小写字母 #define utol(ch) ch=ch>='A'&& ch<='Z' ? ch+'a'-'A':ch

17

⑵ 定义一个带参数的宏,将两个参数的值交换 #define swap(a,b) { double t; t=a;a=b;b=t; }

⑶ 函数f定义如下,执行语句“m=f(5);”后,m的值应为 8 。 int f(int k)

{ if(k==0||k==1) return 1; else return f(k-1)+f(k-2); }

⑷ 函数f定义如下,执行语句“sum=f(3)+f(3);”后,sum的值应为 6 。 int f(int m)

{ static int i=0; int s=0;

for(;i<=m;i++) s+=i; return s; }

⑸ 对下列函数f,f(f(4))的值是 5 。 int f(int x)

{ static int k=0; x+=k++; return x; }

3. 写出下列程序的输出结果

程序⑴ #include #define S x=y=z

#define P3(x,y,z) printf(\ void main() { int x,y,z;

S=1; ++x||++y||++z; P3(x,y,z); S=1; ++x&&++y||++z; P3(x,y,z); S=-1; ++x||++y&&++z; P3(x,y,z); S=-1; ++x&&++y&&++z; P3(x,y,z); }

输出结果为 x=2 y=1 z=1 x=2 y=2 z=1

x=0 y=0 z=-1 x=0 y=-1 z=-1

程序⑵ #include

int func1()

{ static int s=1; s+=2; return s; }

int func2()

{ int s=1; s+=2; return s; } void main() { int i;

for(i=0;i<2;i++) printf(\

18

printf(\ }

输出结果为 func1=3 func1=5 func2=3 func2=3

程序⑶ #include

int i=1,reset(),next(int),last(int),New(int); void main() { int i,j; i=reset();

for(j=1;j<=3;j++) {

printf(\

printf(\ printf(\

printf(\ } }

int reset() 输出结果为 i=1,j=1 { return i; } next(1)=1 int next(int j) last(1)=10 { return j=i++; } new(1+1)=12 int last(int j) i=1,j=3 { static int i=10; next(1)=2 return j=i--; last(1)=9 } new(1+2)=13 int New(int i) i=1,j=3 { int j=10; next(1)=3 return i=j+=i; last(1)=8 } new(1+3)=14

4.根据下列各小题题意编程。

⑴ 编程,输入3个数后输出其中绝对值最小的数。要求定义带参数的宏,计算两个数中绝对值最小的数。

解答: #include #include

#define min(a,b) fabs(a)

{ float a1,a2,a3,x;

scanf(\

x=min(a1,a2); x=min(x,a3); printf(\ }

⑵ 编程,用梯形公式求函数 f(x)=x-sinx在[0,1]区间的定积分,要求用带参数的宏定义函数f(x)的计算公式。

解答: #include #include

#define f(x) (x)*(x)-asin(x)

2

-1

19

void main()

{ double x=0,y=0;

for(int i=1;i<=10;i++) { y=y+(f(x)+f(x+0.1))/20; x=x+0.1;} printf(\ }

习 题 七

1. 单项选择题

⑴ 下列数组声明语句中,正确的是【C】

A、int a[]={1,2,,4,5}; B、char a[5]={A,B,C,D,E}; C、int a[5]={1,2}; D、char a[5]=\

⑵ 数组声明语句为“int a[6];”,输入数组所有元素的语句应为【B】 A、scanf(\

B、for(int i=0;i<6;i++) scanf(\ C、for(int i=0;i<6;i++) scanf(\ D、for(int i=0;i<6;i++) scanf(\

⑶ 数组声明语句为“float a[3][4];”,引用第3行第1列的元素写作【A】 A、**(a+2) B、*(*a+2) C、a[3][1] D、*(a[3]+1) ⑷ 初始化多维数组的语句中,可以缺省的是【B】

A、最后1个下标界 B、第1个下标界 C、第2个下标界 D、以上都不对 ⑸ 数组声明为“int y[4][3];”,表达式“*(y+2)+2-*y”的值为【D】 A、10 B、20 C、16 D、8 ⑹ 数组声明为“char str1[20]=\”, 调用函数“strcpy(str1,str2);”后,字符串str1的串长是【C】 A、13 B、15 C、6 D、7 ⑺ 数组声明为“char str1[20]=\”, 调用函数“strcat(str1,str2);”后,字符串str1的串长是【A】 A、13 B、15 C、6 D、7 ⑻ 表达式“strcmp(\”的值为【C】 A、0 B、3 C、1 D、-3

2. 填空题。

⑴ 未初始化的int类型数组,其各元素的值是 0 。

⑵ 初始化时没有被赋值的字符类型数组元素,它们的值为 '\\0' 。 ⑶ 数组声明为“int a[6];”,数组元素a[1]是否又可以写作“*(a++)”? 原因是 不可以,数组名(地址常量)不可改变 。

⑷ 引用二维数组a第i行、j 列的元素(i、j为0表示第1行、第1列),可以写 作 *(*(a+i-1)+j-1) 或 a[i-1][j-1] 。

⑸ 数组声明为“int a[6][6];”,表达式“*a+i”是指 第1行第i+1个元素的地址、 “*(a+i)”是指 第i+1行第1个元素的地址、“**a”又是指a[0][0]。 ⑹ 数组声明为“float x[7][5];”,若x[6][4]是内存中从x[0][0]数起的第35个 元素,则x[4][4]是第 25 个元素。

20

⑺ 声明“char str1[20]=\后,使字符串str1为\的赋 值表达式,应为 str1[7]='\\0' 。

⑻ 将包括空格在内的6个字符串输入到字符数组a[6][20]中,输入语句可以写作 for(i=0;i<6;i++) gets(a[i]); 。

3. 按照下列各题题意编程。

⑴ 输入平面上凸10边形各点x、y坐标,计算并输出各点之间距离之和。 解答: #include #include void main()

{ float x[10],y[10],s=0; int i;

for(i=0;i<10;i++) scanf(\ for(i=0;i<9;i++)

for(j=i+1;j<10;j++)

s+=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); printf(\ }

⑵ 编程,计算多项式 a0+a1x+a2x+a3x+...+ an-1x的和(n≤30)。 解答: #include void main()

{ float a[30],x,y; int i,n,t; scanf(\

for(i=0;i

for(i=1;i

⑶ 输入n(n≤20)个数,按绝对值从小到大排序后输出。 解答: #include #include void main()

{ float a[20],temp; int i,j,k;

for(i=0;i<20;i++)scanf(\ for(i=0;i<19;i++) {

k=i; for(j=i+1;j<20;j++)if(fabs(a[j])

for(i=0;i<20;i++)printf(\ printf(\ }

⑷ 输入一个5行、6列的数组,先以5行6列的格式输出该数组,然后找出该数组中值最小的元素、输出该元素及其两个下标值。

解答: #include void main()

{ float a[5][6],min; int i,j,k,l;

2

3

n-1

21

for(i=0;i<5;i++) for(j=0;j<6;j++)scanf(\ for(i=0;i<5;i++) {

for(j=0;j<6;j++) printf(\ }

min=a[0][0];k=0;l=0;

for(i=0;i<5;i++) for(j=0;j<6;j++)

if(a[i][j]

⑸ 输入一个5行、6列的数组,将每1行的所有元素都除以该行上绝对值最大的元素,然后输出该数组。

解答: #include #include void main()

{ float a[5][6],max; int i,j;

for(i=0;i<5;i++) for(j=0;j<6;j++) scanf(\ for(i=0;i<5;i++) { max=a[i][0];

for(j=1;j<6;j++) if(fabs(a[i][j])>fabs(max))max=a[i][j]; for(j=0;j<6;j++)a[i][j]/=max; }

for(i=0;i<5;i++) {

for(j=0;j<6;j++)printf(\ printf(\ } }

⑹ 输入一个字符串(串长不超过60),删除字符串中所有的空格符。如输入字符串为 \i= x1 + y ; \,处理后的字符串为 \。 解答: #include #include void main()

{ char s[61]; int i,n,k; gets(s); while(1){

k=0; n=strlen(s);

while(s[k++]!=' ' && k

if(k

printf(\ }

⑺ 输入20个字符串到字符数组str[20][30],统计其中相同字符串个数的最大数。

解: #include #include void main()

{ char str[20][30]; int i,j,k=0,k1; for(i=0;i<20;i++) gets(str[i]);

22

for(i=0;i<20;i++) {

k1=0; for(j=i+1;j<20;j++) if(strcmp(str[i],str[j])==0) k1++; if(k1>k)k=k1; }

printf(\ }

4. 写出下列程序的输出结果

程序⑴ #include void main()

{ int m[]={1,2,3,4,5,6,7,8,9},i,j,k; for(i=0;i<4;i++) {

k=m[i]; m[i]=m[8-i]; m[8-i]=k;

for(j=0;j<9;j++) printf(\ putchar('\\n'); } }

输出结果为 9 2 3 4 5 6 7 8 1

9 8 3 4 5 6 7 2 1 9 8 7 4 5 6 3 2 1 9 8 7 6 5 4 3 2 1

程序⑵ #include void main()

{ int x[4][4]={{1,2,3,4},{3,4,5,6},{5,6,7,8},{7,8,9,10}},i,j; for(i=0;i<4;i++) for(j=0;j<4;j++)

*(*(x+i)+j)/=*(*(x+i)+i); for(i=0;i<4;i++) {

for(j=0;j<4;j++) printf(\ putchar('\\n'); } }

输出结果为 1 2 3 4 0 1 5 6 0 9 1 8 0 0 0 1

程序⑶ #include #include void main()

{ char line[]=\ int i,k=strlen(line);

for(i=0;i<4;i++) { line[k-i]='\\0'; puts(line+i);} }

输出结果为 123456789 2345678

23

34567 46

5. 根据下列各题题意填空,将程序补充完整。

⑴ 输入10个数,输出其中与平均值之差的绝对值为最小的数。 #include #include void main()

{ float a[10],s,d,x; int i;

for(i=0;i<10;i++) scanf(\ s=0;

for(i=0;i<10;i++) s+=a[i]; s/=10; d=fabs(a[0]-s); x=a[0] ; for(i=1;i<10;i++) if(fabs(a[i]-s)

d= fabs(a[i]-s) ; x=a[i]; }

printf(\ }

⑵ 输出如下形式的二项式系数表(以6行为例)。要求表的行数在运行时输入,若小于1或者大于10则重新输入。 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 程序如下:

#include void main()

{ int a[10][10]={{0}},i,j,n;

while( scanf(\ for(i=0;i

for(j=1;j

for(j=0;j<=i;j++) printf(\ putchar('\\0') ; } }

⑶ 输入一个字符串(串长不超过60),将字符串中连续的空格符保留1个。如输入字符串为 \,输出字符串为 \。 #include #include

24

void main() { char b[61]; int i; gets(b);

for(i=1; b[i]!='\\0' ;i++) if(b[i-1]==' '&&b[i]==' ') {

strcpy (b+i-1,b+i); i--; /* 提示: 此处填入正确的函数名 */ }

puts(b) ; }

6. 输入2个数组,每个数组不超过10个元素,将只在其中一个数组出现的数输出。

解答: #include void main()

{ float a[10],b[10]; int m,n,i,j; scanf(\ for(i=0;i

for(j=0;j

putchar(\ for(i=0;i

for(j=0;j

putchar('\\n'); } 7. 输入10个数到数组a[10],用插入法按值从大到小排序(第1个数直接存入a[0],在输入

第i个数之前,先将已输入的i-1个数在a[1]至a[i-1]中按值从大到小排序)。

解答:#include void main()

{ float a[10],x; int i,j,k,n; for(i=0;i<10;i++) { scanf(\

if(i==0) { a[0]=x; n=0; } else {

for(j=0;j<=n;j++) if(x>a[j]) {for(k=n;k>=j;k--)a[k+1]=a[k];break;}

a[j]=x; n++; } }

for(i=0; i<10; i++) printf(\ putchar('\\n'); }

25

8. 输入4行字符,每行不超过60个字符。将其中所有的字符 '$' 改作 'S'。

解答: #include #include void main()

{ char s[4][61]; int i,j,k; for(i=0;i<4;i++) gets(s[i]); for(i=0;i<4;i++)

for(j=0;j

解答: #include #include void main()

{ char s[4][61]; int i,j,k; for(i=0;i<4;i++) gets(s[i]); for(i=0;i<4;i++)

for(j=0;j<=strlen(s[i]);j++)

if(s[i][j]=='$') strcpy(s[i]+j,s[i]+j+1); for(i=0;i<4;i++) puts(s[i]); }

10. 输入4行字符,每行不超过60个字符。将空格符后的第1个英文字母改为大写(原为大写

字母则不变)。

解答:#include #include #include void main()

{ char s[4][61]; int i,j,flag; for(i=0;i<4;i++) gets(s[i]); for(i=0;i<4;i++) { flag=1;

for(j=0;j<=strlen(s[i]);j++) {

if(flag==1 && slower(s[i][j])) { flag=0; s[i][j]-=32; } else if(s[i][j]==' ') flag=1; else flag=0; } }

for(i=0;i<4;i++) puts(s[i]); }

习 题 八

⒈ 单项选择题

⑴ 下列语句定义px为指向int类型变量x的指针,正确的是【D】

A、int *px=x,x; B、int *px=&x,x; C、int x,*px=x; D、int *px,x;p=&x;

26

⑵ 指针变量p1、p2类型相同,要使p2、p2指向同一变量,正确的是【A】 A、p2=*&p1; B、p2=**p1; C、p2=&p1; D、p2=*p1; ⑶ 声明语句为“char a='%',*b=&a,**c=&b”,下列表达式中错误的是【 】 A、a==**c B、b==*c C、**c=='%' D、&a=*&b ⑷ 数组定义为“int a[4][5];”,下列哪一个引用是错误的【D】 A、*a B、*(*(a+2)+3) C、&a[2][3] D、++a ⑸ 表达式“c=*p++”的执行过程是【A】

A、复制*p的值给c后再执行p++ B、复制*p的值给c后再执行*p++ C、复制 p的值给c后再执行p++ D、执行p++后将*p的值复制给c

⑹ 声明语句为“char s[4][15],*p1,**p2; int x,*y;”,下列语句中正确的是【D】 A、p2=s; B、y=*s; C、*p2=s; D、y=&x; 2. 填空题

⑴ 声明flaot类型变量x和指向x的指针变量px的语句是 float x,*px=&x 。 ⑵ 声明语句为“char a[5][9],*pa[5];”。为指针数组pa各元素顺序赋值a数组各行首地址值的循环结构可以写作 for(i=0;i<5;i++) pa[i]=a[i]; 。

⑶ 声明fg为指向返回值为float类型、形参依次为 float**、int、int类型变量的函数的指针,声明语句为 float (*fg)(float**,int,int); 。

⑷ 编制函数find_ch,在一个字符串中查找字符ch第一次出现的位置,返回值为所找到字符的地址,函数find_ch的原型应为 char* find_ch(char *s,char ch) 。

⑸ 动态分配n个int类型数据的存储空间,并将该存储空间的首地址返回给指向int类型数据的指针变量p,写作语句 p=(int*)malloc(n*sizeof(int)) 。 3. 阅读下列程序,指出程序中的错误并说明错误的原因。

程序 ⑴ 程序 ⑵ #include #include void main() void main()

{ char *p; char s[80]; { float x,y; int *p; p=s[0]; scanf(\ printf(\ } }

程序 ⑶ 程序 ⑷ #include #include void main() void main() { int x,*p; { int *p=&a; *p=x; int a;

printf(\ } }

解答:⑴ 语句p=s[0]错误,应赋地址常量 ⑵ 语句y=*p错误,p为悬挂指针

⑶ 语句*p=x错误,p为悬挂指针 ⑷ 语句int *p=&a;错误,a此时未分配存储空间

4. 声明语句为“int a[3][5]={{1,3,5,7,9},{11,13,15,17,19},{21,23,25,27,29}}”,数组a在内存中一维、连续存放且首地址为63fdf8,已知表达式sizeof(int)值为4,写出下列表达式的值并说明它们的含义(指针常量的级、指向或数组元素)。

a(第1行行地址) *a(第1行第1个元素地址) a+2(第3行行地址)

27

&a[0](第1行行地址) a[0]+3(第1行第4个元素地址) *(a+1)(第2行第1个元素地址) *(a+2)+1(第3行第2个元素地址) *(a[1]+2)(等价于a[1][2]) &a[0][2] (第1行第3个元素地址) *(*(a+2)+3)(等价于a[2][3]) a[2][3] &**a(第1行第1个元素地址) 5. 按照下列各题题意编程

⑴ 编程,输入10个数,按绝对值从小到大排序后输出。 解答: #include void main()

{ float *p,temp; int i,j,k;p=(float*)malloc(10); for(i=0;i<10;i++)scanf(\ for(i=0;i<9;i++){ k=i; for(j=i+1;j<10;j++)

if(fabs(p[j])

for(i=0;i<10;i++) printf(\ printf(\ }

⑵ 编程,对n个输入数按绝对值从小到大排序后输出(运行时先输入n的值,然后用malloc函数为数组动态分配存储单元)。

解答: #include void main()

{ float *p,temp,int i,j,k,n; scanf(\ for(i=0;i

⑶ 编制函数,接受从主调函数传入的、有n个元素的一维数组首地址,对该数组按绝对值从小到大排序。

解答: #include #include

void sort(float *p, int n) { float temp; int i,j,k; for(i=0; i

for(j=i+1;j

void main()

{ float *a; int i,n;

scanf(\ for(i=0;i

sort(a,n); for(i=0;i

28

6. 有n个人围成一圈,顺序排号,从第1个人开始报数,从1报到m,凡报到m的人退出圈子,问最后留下的是原来第几号的人?下列函数完成上述处理,其中m、n(m

int del_n(int n,int m) { int *p,i,del=0,k=0;

p= (int*) malloc(n*sizeof(int)); for(i=0;i

if( k==m ) { del++; p[i]=0; k=0;} } }

for(i=0;i

7. 编制函数,在主调函数的一维数组中查找最大值及该元素下标、最小值及该元素下标。请适当选择参数,使所求结果能传递到主调函数。

解答: void find(float *a,int n,float *max,int *k1,float *min,int *k2) { int i; *max=*min=*a; *k1=*k2=0; for(i=1;i

if(a[i]>*max) { *max=a[i]; *k1=i; }

else if(a[i]<*min) { *min=a[i]; *k2=i; } } 8. 编制函数,将一个字符串中的所有大写字母转换为相应的小写字母。

解答: char *utol(char *str) { int i;

for(i=0;i

if(isupper(str[i])) str[i]=str[i]+32; } 9. 写出下列程序的输出结果。

#include #include void del_bk(char *p) { char *p1; p1=p; while(*p1!='\\0')

if(*p1==' '&&*(p1+1)==' ') strcpy(p1,p1+1); else p1++; }

void main()

{ char aa[]=\

printf(\

29

}

输出结果: aa bb cccc ddd efg h aa bb cccc ddd efg h

10. 编制函数,将字符串中连续的相同字符仅保留1个(字符串\处理后为\)。

解答:#include #include void sub(char *p) { int i, j;

for(i=1;i

for(j=i;j

11. 下列程序求二维数组a中最大值与b中最大值之差,填空将下列程序补充完整。

#include #include

float find_max( float **x,int m,int n) { int i,j; float max=x[0][0]; for(i=0;i

if(*(*(x+i)+j)>max) max= *(*(x+i)+j); 或 x[i][j]; return max; }

void main()

{ float a[5][5],b[6][4], *pa[5],*pb[6] ; int i,j; for(i=0;i<5;i++) pa[i]=a[i]; for(i=0;i<6;i++) pb[i]=b[i];

for(i=0;i<5;i++) for(j=0;j<5;j++) scanf(\ for(i=0;i<6;i++) for(j=0;j<4;j++) scanf(\ printf(\ } 12. 编制函数,将float类型二维数组的每一行同除以该行上绝对值最大的元素。要求分别以8.4.2节介绍的两种方法编写,并上机调试。

解答:方法一:

#include #include

void f(float **x, int m, int n) { int i,j; float max; for(i=0;i

for(j=1;jfabs(max)) max=x[i][j]; for(j=0;j

30

} }

void main()

{ float a[5][6]; int i,j; float *b[5];

for(i=0; i<5; i++) for(j=0;j<6;j++) scanf(\ for(i=0;i<5;i++) b[i]=a[i]; f(b,5,6);

for(i=0;i<5;i++) { for(j=0;j<6;j++) printf(\ \putchar('\\n');}

} 方法二:

#include #include

void f(float *p, int m, int n) { int i,j; float max; for(i=0;i

for(j=1;jfabs(max)) max=p[i*n+j]; for(j=0;j

void main()

{ float a[5][6]; int i,j;

for(i=0;i<5;i++) for(j=0;j<6;j++) scanf(\ f(a[0],5,6)

for(i=0; i<5; i++)

{ for(j=0;j<6;j++) printf(\ } 13. 编制函数,在字符串数组中查找与另一字符串相等的字符串,函数返回值为该字符串的地址或NULL(当查找不到时)。

解答: #include #include

char *str(char *str[], int n, char *s) { int i;

for(i=0; i

void main()

{ char *s[5]={\ printf(\ } 14. 下列程序中,函数find_data在已从小到大排序好的数组中寻找指定数data,采用二分查找算法,找到则返回该数组元素地址,找不到返回NULL。请填空将程序补充完整。

#include

float* find_data(float *a,int n,float data)

31

{ int low,mid,high ; low=0; high=n-1; while(low<=high) { mid=(low+high)/2; if(a[mid]>data) high=mid-1; else

if(a[mid]

return NULL ; }

void main()

{ float b[10],*p,data;

for(int i=0;i<10;i++) scanf(\要求输入数据值从小到大 */ scanf(\输入待查找的数据 */ p=find_data(b,10,data); if(p) printf(\

else printf(\查找不到%f\\n\ }

67?2(x2?x?sinx)dx??3(log10x2?x?3)dx15. 程序填空,将求下列两个定积分之和的程序补充完整。

其中,求定积分的函数采用用梯形公式n(main中对应的实参取50)等份积分区间。 #include #include

float f1(float),f2(float);

float fs( float a,float b,int n, float(*f)(float)) { float s=0,x=a,h=(b-a)/n; int i;

for(i=1;i<=n;i++) { s+=((*f)(x)+(*f)(x+h))*h/2; x+=h; } return s ; }

void main() { float y;

y=fs(2,6,50,f1)+fs(3,7,50,f2); printf(\ }

float f1(float x)

{ return x*x+x*sin(x); } float f2(float x)

{ return log10(x*x)-x+3 ;}

32

习 题 九

1. 构造一个表示通讯录中每个“记录”的数据类型,声明该类型的标识符。

解答:struct person{ char name[9];int pho;};

⒉ 编程,先输入n,再输入通讯录中若干个人的记录到结构体数组中,按电话号码的升序对结构体数组排序后输出。

解答: #include #include

struct person{ char name[9]; int pho; }; void main()

{ struct person *p,temp; int n,i,j,k;

scanf(\ for(i=0;i

k=i; for(j=i+1;j

for(i=0;i

解答: #include #include

struct person{ char name[9]; int pho; }; void sort(struct person *p,int n) { struct person temp; int i,j,k; for(i=0;i

k=i; for(j=i+1;j

void main()

{ struct person *p,temp; int n,i,j,k; scanf(\p=(struct person*) malloc(n*sizeof(struct person)); for(i=0;i

for(i=0;i

解答: #include #include #include

struct node { char x; struct node* t; }; void main()

{ struct node *h=NULL,*p1,*p2; char ch;

33

while((ch=getchar())!='.') {

p2=(struct node*) malloc(sizeof(struct node)); p2->x=ch; if(h==NULL) h=p1=p2; else { p1->t=p2; p1=p2;} }

p2->t=NULL; p1=h;

while(p1!=NULL){ if(isalpha(p1->x))putchar(p1->x); p1=p1->t; } putchar('\\n'); }

5.阅读下列程序,写出输出结果。

程序⑴ #include void main()

{ struct T1{ char c[4],*s;} s1={\ struct T2{ char *cp; T1 ss1;} s2={\ printf(\ printf(\ printf(\ printf(\ }

输出结果为 a,d abc,def ghi,mno hi,no

程序⑵ #include #include void main()

{ struct info { int data; info *pn; } info *base,*p; base=NULL;

for(int i=0;i<10;i++) {

p=(inf*) malloc(sizeof(struct info)); p->data=i+1; p->pn=base; base=p; }

p=base;

while(p!=NULL) {

printf(\ }

printf (\ }

输出结果为 10 9 8 7 6 5 4 3 2 1

6.下列函数用于将节点类型为ntab的链表中某个结点(数据成员data与形参num匹配)删除,填空将函数补充完整。

解答: struct ntab* del_node(struct ntab *h, int num) { struct ntab *p1,*p2;

if(h==NULL) { printf(\ p1=h;

while(num!=p1->data && p1->next!=NULL) { p2=p1; p1=p1->next; } if(num==p1->data)

34

if(p1==h) { h=p1->next; free(p1); } else { p2->next=p1->next; delete p1; } else

printf(\ return h; }

7.下列函数用于在节点类型为ltab的非空链表中插入一个节点(由形参指针变量p0指向),链表按照节点数据成员no的升序排列,填空将函数补充完整。

解答: struct ltab* insert(struct ltab* head,struct ltab* stud) { struct ltab *p0,*p1,*p2; p1=head;p0=stud;

while((p0->no>p1->no)&&( p1->next!=NULL)){ p2=p1; p1=p1->next; } if(p0->no<=p1->no)

if(head==p1) { p0->next=head; head=p0; } else { p2->next=p0; po->next=p1; } else { p1->next=p0; p0->next=NULL; } return (head); }

习 题 十

1. 计算下列表达式的值。

⑴ 5&7 ⑵ -12&6 ⑶ 7|8 ⑷ -12||32 ⑸ (x=13)^9 ⑹ 15/2^1 ⑺ ~-15 ⑻ ~15/3 ⑼ 7<<2 ⑽ -9<<2 ⑾ (x=13)>>3 ⑿ -9>>3 解答:⑴ 5 ⑵ -5 ⑶ 15 ⑷ 1 ⑸ 4 ⑹ 6 ⑺ 14 ⑻ -5 ⑼ 28 ⑽ -36 ⑾ 1 ⑿ -2 2. 变量a、b均被声明为short类型,分别写出执行下列语句后a、b的值。

⑴ a=4;b=5;a&b; ⑵ a=-4;b=a|6; ⑶ a=3;b=a<<2; ⑷ a=-15;b=~a>>2 解答:⑴ a=4,b=5 ⑵ a=-4,b==2 ⑶ a=3,b=12 ⑷ a=-15,b=3 3. 阅读下列程序,写出运行时输入 6 8 8 4 12 -5 23 -12 ^z 的输出结果。 #include

void sub1(short *x,short *y) { *x=*x^*y; *y=*x^*y; *x=*x^*y; } void main() { short a,b;

while(scanf(\ sub1(&a,&b); printf(\ } }

解答:交换 a、b 的值。 4. 编程,输入一个int类型数据后,输出该数的机内码。

解答: #include void main()

{ int a,i; char b[33]={'\\0'};

35

scanf(\

for(i=31;i>=0;i--){ b[i]=(char)((a&1)+'0');a=a>>1; } puts(b); }

5.输入1个short类型数据,显示它二进制数奇数位(即从左边起的第1、3、5、??、15位)。

解答:#include

void main()

{ short a,i; char b[9]={'\\0'}; scanf(\

for(i=7;i>=0;i--){ b[i]=(char)((a&1)+'0');a=a>>2; } puts(b); }

6.输入一个整数,将其低8位全置1,高8位保留,并以十六进制输出该数。

解答:#include void main()

{ int a; scanf(\

a=a|0xff; printf(\ }

习 题 十一

⒈ 写出下列fopen函数调用所打开文件的读写方式与文件存储格式。

⑴ fpt=fopen(\⑵ fpt=fopen(\⑶ fpt=fopen(\⑷ fpt=fopen(\⑸ fpt=fopen(\

解答:⑴ 新建文本文件 ⑵ 新建二进制文件 ⑶ 可读写文本文件 ⑷ 追加记录二进制文件 ⑸ 新建可读写文本文件 ⒉ 填空题

⑴ fopen函数的返回值是 文件读写的首地址或NULL 。

⑵ 文件打开方式为\,文件打开后,文件读写位置在 文件的首纪录前 。 ⑶ 文件打开方式为\,文件打开后,文件读写位置在 文件的末纪录后 。 ⑷ 表达式“fgetc(fpn)”的值为 所读入字符的ASCII值 或 EOF 。 ⑸ 表达式“fgets(a,10,fpn)”的值为 字符串a的地址 或 NULL 。 ⑹ 函数fscanf的返回值为 所读入数据个数 或 EOF 。 ⑺ 函数fread的返回值为所读入数据的个数或 0 。

⑻ 表达式“fscanf(fpn,\”的值为-1时,函数feof()的值为 1 。 3. 编程,输入若干同学的姓名、学号、3门功课成绩,写到文本文件e:\\aaa.txt。

解答:

#include

36

struct stu{char name[9];char numb[9];int score[3];} void main()

{ FILE *fp1; struct stu a; int i,n;

fp1=fopen(\ for(i=1;i<=n;i++) {

scanf(\

fprintf(fp1,\

/* 格式串中各格式符间有空格,在从文件读入数据时可作为间隔符 */ }

fclose(fp1); } 4. 编程,顺序读入题3所建立文本文件中各个同学的姓名、学号、成绩,显示输出。

解答: #include

struct stu{char name[9];char numb[9]; int score[3];}; void main()

{ FILE *fp1; struct stu a;

fp1=fopen(\

while(fscanf(fp1,\ &a.score[1],&a.score[2])!=EOF)

printf(\ a.score[1],a.score[2]); fclose(fp1);

} /* 应参照(题3)文件中数据存储格式,确定读文件时的格式符 */ 5. 编程,输入1个同学的学号,从题3所建立的文本文件中删除该同学的信息。

解答: #include #include

struct stu{char name[9];char numb[9]; int score[3];}; void main()

{ FILE *fp1,*fp2; struct stu a; char x[9]; gets(x);

fp1=fopen(\ while(fscanf(fp1,\ &a.score[1],&a.score[2])!=EOF)

if(strcmp(a.numb,x))fprintf(fp2,\ a.score[0],a.score[1],a.score[2]); fclose(fp1);fclose(fp2);

remove(\ } 6. 编程,读入若干行字符(每行不超过80个),写入文本文件e:\\bbb.txt。

解答: #include void main()

{ FILE *fp; char a[81];

fp=fopen(\

while(gets(a)!=NULL) { fputs(a,fp); fputc('\\n',fp); }

37

fclose(fp); /* 加入换行符,作为间隔符 */ }

7. 文件a.txt、b.txt中各自存放了若干个整数,编程,显示在a.txt中存在而b.txt中不存在的那些数。

解答: #include void main()

{ FILE *fa,*fb; int a,b;

fa=fopen(\ while(!feof(fa)) { fscanf(fa,\ while(!feof(fb)) {

fscanf(fb,\ }

if(feof(fb)) printf(\ rewind(fb); }

fclose(fa); fclose(fb); }

8. 编程,输入若干同学的姓名、学号、3门功课成绩,写到二进制文件中(文件名自定)。

解答: #include void main()

{ FILE *fp; char name[9],numb[9]; int i,n,score[3]; fp=fopen(\ for(i=1;i<=n;i++) {

scanf(\ fwrite(name,sizeof(name),1,fp); fwrite(numb,sizeof(numb),1,fp); fwrite(score,sizeof(int),3,fp); }

rewind(fp); /* 下面的读文件程序段不是必须的,只是为验证输入是否正确 */

while(fread(name,sizeof(name),1,fp)!=NULL) {

fread(numb,sizeof(numb),1,fp); fread(score,sizeof(int),3,fp);

printf(\

} } 9. 编程,输入1个同学的姓名、学号、3门功课成绩,修改题8所建立的二进制文件中具有相同学号同学的信息。

解答: #include #include void main()

{ FILE *f1,*f2; char name[2][9],numb[2][9]; int s[2][3];

f1=fopen(\ scanf(\

38

while(fread(name[1],sizeof(name[1]),1,f1)!=NULL) { fread(numb[1],sizeof(numb[1]),1,f1); fread(s[1],sizeof(int),3,f1);

if(strcmp(numb[0],numb[1])) {

fwrite(name[1],sizeof(name[1]),1,f2); fwrite(numb[1],sizeof(numb[1]),1,f2); fwrite(s[1],sizeof(int),3,f2); }

else {

fwrite(name[0],sizeof(name[0]),1,f2); fwrite(numb[0],sizeof(numb[0]),1,f2); fwrite(s[0],sizeof(int),3,f2); } }

fclose(f1);fclose(f2);

remove(\ /* 下面的读文件程序段不是必须的,只是为验证输入是否正确 */ f2=fopen(\

while(fread(name[0],sizeof(name[0]),1,f2)!=NULL) { fread(numb[0],sizeof(numb[0]),1,f2); fread(s[0],sizeof(int),3,f2);

printf(\

}

fclose(f2); } 10. 编程,模仿第10章例8,利用按位异或对某一文件加密与解密。

解答: #include void main()

{ char a; int m1,m2,i; FILE *p1,*p2;

printf(\输入一个整数密值(1~255):\\n\ p1=fopen(\ while((a=fgetc(p1))!=EOF) fputc(a^m1,p2);

fclose(p1); fclose(p2); p2=fopen(\ while((a=fgetc(p2))!=EOF) putchar(a^m1); fclose(p2); }

11.文本文件a.txt、b.txt每行存放一个数且均按从小到大存放。下列程序将这两文件中数据合并到c.txt,文件c.txt中数据也要从小到大存放,填空将程序补充完整、正确。

说明:若文件a.txt数据为1↙6↙9↙18↙27↙35↙,b.txt数据为10↙23↙25↙39↙61↙,则文件c.txt中数据应为1↙6↙9↙10↙18↙23↙25↙27↙35↙39↙61。

解答: #include void main()

{ FILE *f1,*f2,*f3; int x,y;

f1=fopen(\

39

⑴ f3=fopen(\

fscanf(f1,\ while(1) if(⑵ x

else { fprintf(f3,\ if( ⑶ feof(f1) ) {

fprintf(f3,\

while(fscanf(f2,\⑷ fprintf(f3,\ }

else {

⑸ fprintf(f3,\

while(fscanf(f1,\ }

fclose(f1); fclose(f2); fclose(f3); }

40