资源描述
7.8 习题
1. 编制一个C程序,从键盘输入一个正整数,如果该数为素数,则输出该素数,否则输出该数的所有因子(除去1与自身)。
2. 编制一个C程序,从键盘输入一个正整数N,然后计算并输出
S=
最后计算并输出
T=
其中的整数部分。
3. 编制一个C程序,计算并输出多项式的值
的值,直到 |Sn-Sn-1|<0.000001 为止。其中x从键盘输入。
4. 编制一个C程序,计算下列级数和:
sn=1+(2/1)+(3/2)+(5/3)+(8/5)+(13/8)+…+(an/an-1)
其中n≥1,由键盘输入;s1=1。
5. 编制一个C程序,计算并输出下列级数之和:
其中n与x从键盘输入。
6. 编制一个C程序,输出能写成两个数平方之和的所有三位数。
7. 如果一个数恰好等于它的所有因子(包括1但不包括自身)之和,则称之为“完数”。例如,6的因子为1、2、3,且1+2+3=6,即6是一个“完数”。编制一个C程序,计算并输出1000以内的所有“完数”之和。
8. 编制一个C程序,从键盘输入30个实数,分别计算并输出以下5个量:所有正数之和,所有负数之和,所有数的绝对值之和,正数的个数,负数的个数。
9. 100元钱买100只鸡,母鸡3元/只,公鸡2元/只,小鸡0.5元/只。编制一个C程序,制定买鸡方案。
10. 设A,B,C,D,E五人,每人额头上贴了一张或黑或白的纸。五人对坐,每人都可以看到其他人额头上的纸的颜色,但都不知道自己额头上的纸的颜色。五人相互观察后开始说话:
A说:我看见有三人额头上贴的是白纸,一人额头上贴的是黑纸。
B说:我看见其他四人额头上贴的都是黑纸。
C说:我看见有一人额头上贴的是白纸,其他三人额头上贴的是黑纸。
D说:我看见四人额头上贴的都是白纸。
E什么也没说。
现在已知额头上贴黑纸的人说的都是真话,额头上贴白纸的人说的都是假话。编制一个C程序,确定这五人中谁的额头上贴白纸,谁的额头上贴黑纸?
11. 寻找1000以内最小的10个素数与最大的10个素数(去掉重复的素数),计算并输出这20个素数之和。
具体要求:
(1) 画出计算过程的结构化流程图。
(2) 虽然1000以内素数个数超过20个,但仍要求考虑1000以内不够10个最小素数与10个最大素数,以及最小的10个素数与最大的10个素数有重复的情况。
(3) 输出要有文字说明。输出形式为
zui xiao su shu :素数1,素数2,…,素数10
zui da su shu : 素数1,素数2,…素数10
su shu zhi he : 和的具体值
(4) 在程序内部加必要的注释(至少有三处)。
方法说明:
对于某个(从小到大与从大到小)自然数k,开始时置标志flag为0,然后对2到中的自然数j进行检测,当发现j是k的因子,就置flag为1,表示不必再对别的自然数进行检测,因为此时已经可以确定k不是素数了,只有当2到中的所有自然数都不是k的因子(即flag保持为0)时,说明k为素数,输出k,并进行累加。
12. A、B、C、D、E五人分苹果。A将所有的苹果分为五份,将多余的一个苹果吃掉后再拿走自己的一份苹果;B将剩下的苹果分为五份,将多余的一个苹果吃掉后再拿走自己的一份苹果;C、D、E依次按同样的方法,将剩下的苹果分为五份,吃掉多余的一个苹果后拿走自己的一份苹果。编程计算原来至少有多少个苹果?A、B、C、D、E各得到多少个苹果?
具体要求:
(1) 画出计算过程的结构化流程图。
(2) 输出要有文字说明。
(3) 在程序内部加必要的注释(至少有三处)。
方法说明:
采用逐步试探的方法。
设当前试探的苹果数为n。如果n满足下列条件:
n-1(多余的一个被吃掉)后要能被5整除;
拿走一份后,余下的四份苹果数为4*(n-1)/5。
按上述策略连续进行五次分配,如果每次分配时均满足其中的条件,则试探的n即为原来的苹果数x。
为了第一次能分配,试探从6开始。
根据分配策略,最后A,B,C,D,E五人得到的苹果数(不包括吃掉的一个苹果)可以按如下公式依次计算:
a=(x-1)/5
b=(4*a-1)/5
c=(4*b-1)/5
d=(4*c-1)/5
e=(4*d-1)/5
13. 某单位要在A,B,C,D,E,F六人中选派若干人去执行一项任务,选人的条件如下:
(1) 若C不去,则B也不去;
(2) C和D两人中去一个;
(3) D和E要么都去,要么都不去;
(4) A,B,F三人中要去两个;
(5) C和F不能一起去:
(6) E和F两人中至少去一个。
问应该选哪几个人去?
具体要求:
(1) 画出计算过程的结构化流程图。
(2) 输出要有文字说明。
(3) 在程序内部加必要的注释(至少有三处)。
8.5 习题
1. 编写一个函数sabc(),根据给定的三角形三条边长a,b,c,函数返回三角形的面积。
2. 编写一个计算阶乘值的函数p()(该函数为双精度实型);再编写一个主函数,从键盘输入两个正整数m与n(m≥n),通过调用函数p(),计算 的值(即求 )。
3. 编写一个函数,计算并返回给定正整数m与n的最大公约数。
4. 编写一个主函数,调用例8.3中的函数sushu(),输出小于1000的最大五个素数。
5. 编写一个主函数,调用例8.3中的函数sushu(),验证6到1000中的所有偶数均能表示成两个素数之和。
6. 编写一个递归函数,计算并返回菲波那契(Fibonacci)数列中第n项的值。菲波那契数列的定义如下:
Fib(1)=1,Fib(2)=1
Fib(n)=Fib(n-1)+Fib(n-2)
7. 编写一个递归函数,计算并返回阿克玛(Ackermann)函数值。阿克玛函数的定义如下:
其中n,x,y均为非负整数。
8. 编写计算n!的递归函数。
9. 编写一个递归函数,其功能是将一个正整数n转换成字符串(要求各字符之间用一个空格分隔)输出。例如,输入的正整数为735,应输出字符串“7 3 5”。其中正整数在主函数中从键盘输入,要求判断其输入的合理性。
10. 计算并输出500以内的所有“亲密数”对,并输出所有“完数”之和。
具体要求:
(1) 编写一个函数facsum(n),返回给定正整数n的所有因子(包括1但不包括自身)之和。
(2) 编写一个主函数,调用(1)中的函数facsum(n),寻找并输出500以内的所有“亲密数”对以及计算所有“完数”之和。
(3) 分别画出函数facsum(n)和主函数计算过程的结构化流程图。
(4) 在输出每对“亲密数”时,要求小数在前、大数在后,并去掉重复的数对。例如,220与284是一对“亲密数”,而284与220也是一对“亲密数”,此时只要求输出220与284这对“亲密数”。
(5) 输出要有文字说明(英文或汉语拼音)。输出时每对“亲密数”用一对圆括号括起来,两数之间用逗号分隔,且所有的“亲密数”对占一行。输出形式为
各对“亲密数”
“完数”之和
(6) 在程序内部加必要的注释(至少有三处)。
(7) 将两个函数分别放在两个文件中进行编译、连接并运行。
(8) 将两个函数放在一个文件中进行编译、连接并运行。
方法说明:
如果自然数M的所有因子(包括1但不包括自身,下同)之和为N,而N的所有因子之和为M,则称M与N为一对“亲密数”。例如,6的所有因子之和为1+2+3=6,因此,6与它自身构成一对“亲密数”;又如,220的所有因子之和为1+2+4+5+10+11+20+22+44+55+110=284,而284的所有因子之和为1+2+4+71+142=220,因此,220与284为一对“亲密数”。
如果一个自然数的所有因子之和恰好等于它自身,则称该自然数为“完数”。例如,6不仅与它自身构成一对“亲密数”,且6是一个“完数”。
11. 计算并输出的值。
具体要求:
(1) 编写一个计算k!的递归函数,其函数名返回k!的值。
(2) 编写一个主函数,首先从键盘输入m和n的值(要求n≥m≥0),然后调用(1)中的函数计算的值。
(3) 在计算k!的递归函数中,要检查形参k的合理性,当k<0时,应输出出错信息,并返回0值。
(4) 在主函数中应检查从键盘输入的数据的合理性,对于不合理的输入,应输出出错信息,并不再调用计算。
(5) 分别输入(m, n)=(-3, 7), (0, 0), (1, 7), (9, 13), (9, 4)运行你的程序。
3. 利用变步长梯形求积法计算定积分。
具体要求:
(1) 编写一个函数st(a, b, eps)(要求该函数放在独立的文件中),其功能是利用变步长梯形求积法计算定积分
其中eps为精度要求。
要求画出该函数处理的结构化流程图。
(2) 编写一个主函数以及计算被积函数值的函数fun(x),在主函数中调用(1)中的函数st(a, b, eps),计算并输出下列积分值
精度要求为eps=0.0001。
要求主函数与函数fun(x)放在同一个文件中。
(3) 编写另一个主函数以及计算被积函数值的函数fun(x),在主函数中调用(1)中的函数st(a, b, eps),计算并输出下列积分值
精度要求为eps=0.00001。
同样要求主函数与函数fun(x)放在同一个文件中。
方法说明:
变步长梯形求积法的基本步骤如下:
① 利用梯形公式计算积分。即取
n=1,h=b-a
则有
其中xk=a+kh。
② 将求积区间再二等分一次(即由原来的n等分变成2n等分),在每一个小区间内仍利用梯形公式计算。即有
=
=
③ 判断二等分前后两次的积分值之差的绝对值是否小于所规定的误差。若条件
|T2n-Tn|<eps
成立,则二等分后的积分值T2n即为结果;否则作如下处理:
h=h/2,n=2*n,Tn=T2n
然后重复②。
9.6 习题
1. 编写一个C程序,从键盘为一个长度为10的整型一维数组输入数据。最后按逆序输出数组中的元素,并输出数组中最大元素的下标值。
2. 编写一个C程序,将两个长度相同的一维数组中各下标相同的对应元素相乘,并将结果存放到另一个一维数组中。
3. 编写一个C程序,从键盘为5×5的一个整型二维数组输入数据。最后输出该二维数组中的对角线元素。
4. 编写一个C程序,从键盘为4×6的一个整型二维数组输入数据。最后输出该二维数组中最小元素的行下标与列下标。
5. 从键盘输入5行5列二维整型数组的数据。编制一个函数,计算二维数组中每一行中的最小值,并将此最小值顺序存放在一个长度为5的一维数组中。最后按矩阵形式输出二维数组中的各元素,且各行中的最小值(即一维数组中的元素)输出到相应行的右边。
6. 编写一个C函数,将一个一维数组中的元素逆转。逆转是指将数组中的第一个元素与最后一个元素进行交换,第二个元素与倒数第二个元素进行交换,以此类推,直到数组的中间一个元素为止。
7. 编写一个C函数,将矩阵进行转置后输出。
8. 设有两个整型一维有序数组(即数组中的元素按从小到大进行排列),编写一个C函数,将这两个有序数组合并存放到另一个一维数组中,并保证合并后的一维数组也是有序的。
9. 编制一个C程序,从键盘输入一个由5个字符组成的单词,然后判断该单词是否是China。要求给出判断结果的提示信息。
10. 编写一个C程序,从键盘输入50个字符,并统计其中英文字母(不分大小写)与数字字符的个数。
11. 中国有句俗语叫“三天打鱼,两天晒网”。现某人从2000年1月1日起开始“三天打鱼,两天晒网”,请编程判断此人在以后的某年某月某日是在“打鱼”还是在“晒网”。其中以后的某年某月某日从键盘输入。
12. 一辆汽车在开始出发前其里程表上的读数是一个对称数95859,后匀速行驶两小时后,发现里程表上是一个新的对称数。问该新的对称数是多少?汽车的速度是多少?
注:所谓对称数是指从左向右读与从右向左读完全一样。
13. 计算多项式函数
P6(x)=1.5x6+3.2x5-0.8x4+1.4x3-6.5x2+0.5x-3.7
在x=-2.3,-1.1,-0.6,0.8,2.1,3.6处的函数值。
具体要求:
(1) 编写一个函数,其功能是:给定一个x值,返回多项式函数值。
(2) 编写一个主函数,定义两个一维数组,分别存放多项式的系数和需要计算的各x值。然后在主函数中调用(1)中的函数逐个计算各x值时的多项式值。
(3) 在主函数中的输出形式为
P(x值)=具体的多项式值
…
方法说明:
设多项式为
Pn(x)=anxn+an-1xn-1+…+a1x+a0
可以表述成如下嵌套形式:
Pn(x)=(…((anx+an-1)x+an-2)x+…+a1)x+a0
利用上式的特殊结构,从里往外一层一层地进行计算,即按如下递推关系进行计算:
u=an
u=ux+ak ,k=n-1,…,1,0
最后计算得到的u即是多项式的值Pn(x)。
14. 产生100个0~1之间均匀分布的随机数,并将这些随机数按非递减顺序进行排序,存放到一个一维数组中。最后输出该有序数组。
具体要求:
(1) 在产生随机数的过程中,每产生一个随机数就将它插入到前面已经有序的数组中。
(2) 输出时要求每行输出10个数据,并上下对齐。
方法说明:
产生随机数pk(k=1,2,…,100)的公式为
rk=mod(2053rk-1+13849,216)
pk=rk/216
其中初值r0=1。
解决本问题的流程图如图9.4所示。
定义数组a[100]
r=1, k=0
k<100
r=mod(2053r+13849, 216)
p=r/216
j=k-1
j≥0 且 p<a[j]
a[j+1]=a[j]
j=j-1
a[j+1]=p
k=k+1
输出a[k], k=0, 1, …, 99
图9.4 实验练习2的流程图
15. 利用高斯(Gauss)消去法求解线性代数方程组。
具体要求:
(1) 编写一个用高斯(列选主元)消去法求解给定线性代数方程组的函数
gauss(a, b, x)
其中a为系数矩阵,b为常数向量,x为解向量。
(2) 编写一个主函数,调用(1)中的函数求解下列线性代数方程组:
其中系数矩阵与常数向量利用初始化赋初值。
(3) 在主函数中要求输出系数矩阵与常数向量。输出形式为
MAT A=
1.1161 0.1254 0.1397 0.1490
0.1582 1.1675 0.1768 0.1871
0.2368 0.2471 0.2568 1.2671
0.1968 0.2071 1.2168 0.2271
MAT B=
1.5471 1.6471 1.8471 1.7471
(4) 结果输出形式为
x(1)=具体值
x(2)=具体值
x(3)=具体值
x(4)=具体值
(5) 在函数gauss()中至少要求有五处加注释。
方法说明:
设线性代数方程组为AX=B。高斯消去法求解线性代数方程组的步骤如下:
①对于k从1到n-1,作如下操作:
进行列选主元
akj=akj/akk ,j=k+1,…,n
bk=bk/akk
这一步称为归一化。然后作
aij=aij-aikakj ,i=k+1,…,n;j=k+1,…,n
bi=bi-aikbk,i=k+1,…,n
这一步称为消去。
② 进行回代
xn=bn/ann
,i=n-1,…,2,1
列选主元的基本思想是在变换到第k步时,从第k列的akk以下(包括akk)的所有元素中选出绝对值最大者,然后通过行交换将它交换到akk的位置上。由于交换系数矩阵中的两行(包括交换常数向量中的两个相应元素),只相当于两个方程的位置被交换了,因此,列选主元不影响求解结果。
最后需要说明的是,在C语言中,数组的下标是从0开始的,不是从1开始的。另外,注意在函数gauss()中要将二维数组的下标转换成一维数组的下标。
10.8 习题
1. 阅读下列C程序:
(1)
#include <stdio.h>
main()
{ int a[4][3]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int (*ptr)[3]=a, *p=a[0];
printf("%d\n", *(p+5) + *(*(ptr+1) + 2));
}
输出结果为( )。
(2)
#include <stdio.h>
main()
{ int a[5]={2, 4, 6, 8, 10};
int *p=a, **k, z;
k=&p; z=*p; p=p+1; z=z + **k;
printf("%d\n", z);
}
输出结果为( )。
(3)
#include <stdio.h>
void ast(int x, int y, int *cp, int *dp)
{ *cp=x+y; *dp=x-y;
return;
}
main()
{ int a, b, c, d;
a=4; b=3;
ast(a, b, &c, &d);
printf("%d\n", c+d);
}
输出结果为( )。
2. 编写一个C程序,从键盘输入两个字符串,然后按先小后大的顺序显示输出。
3. 编写一个C程序,利用指针数组,显示输出如下信息:
File
Edit
Write
Read
Exit
4. 编写函数void disp(char *s, int n),将在s指向的字符串中连续显示输出n个字符,若字符串中不够n个字符,则输出到字符串结束符为止。再编写一个主函数,从键盘输入一个字符串,调用函数disp(),将该字符串中的第4到第10个之间的字符显示输出。
5. 编写一个函数,功能是计算给定字符串的长度。再编写一个主函数调用该函数来计算字符串的长度,其中字符串在执行程序时的命令行中作为参数输入。
6. 利用指针数组实现矩阵相乘C=AB。其中矩阵相乘函数为通用的,在主函数中对矩阵A与B进行初始化,并显示输出矩阵A、B与乘积矩阵C。
7. 编写一个C函数,将一个字符串连接到另一个字符串的后面。
8. 编写一个C函数,将两个有序字符串(其中字符按ASCII码从小到大排列)合并到另一个有序字符串中,要求合并后的字符串仍是有序的。
9. 编写一个C程序,从键盘输入一个月份号,输出与之对应的英文名称。例如,输入“5”,则输出“MAY”。要求用指针数组处理。
10. 编写一个C函数int str_cmp(char *str1, char *str2),实现两个字符串的比较(即实现strcmp(str1, str2)的功能)。
11. 编写一个主函数,其功能是将执行该程序时所输入的命令行中所有的字符串显示输出。
12. 计算给定复数z=x+jy的指数ez、对数ln(z)以及正弦sin(z)、余弦cos(z)。
具体要求:
(1) 分别编写计算给定复数的指数、对数、正弦和余弦的四个函数。这四个函数的形参分别是给定复数的实部x、虚部y以及计算结果的实部u、虚部v。并且,在每一个函数中应允许存放计算结果的变量与给定复数的变量具有相同的存储地址。
(2) 编写一个主函数,首先调用计算复数指数的函数计算并输出复数z=2+j3的指数,再调用复数对数的函数计算并输出该结果(为一个复数)的对数,然后调用计算复数正弦的函数计算并输出新结果(为一个复数)的正弦,最后调用计算复数余弦的函数计算并输出新结果(为一个复数)的余弦。
(3) 在主函数中输出结果的形式为(其中x与y为复数实部与虚部的具体值,u与v为计算结果中实部与虚部的具体值)
exp(x+jy)=u+jv
ln(x+jy)=u+jv
sin(x+jy)=u+jv
cos(x+jy)=u+jv
方法说明:
设给定的复数为z=x+jy。则
(1) 复数z的指数为
w=u+jv=ez=ex+jy
=ex(cos(y)+jsin(y))
即u=excos(y),v=exsin(y)。
(2) 复数z的对数为
w=u+jv=ln(z)=ln(x+jy)
=ln+jArctg(y/x)
即u=ln,v=Arctg(y/x)。
(3) 复数z的正弦为
w=u+jv=sin(z)=sin(x+jy)
=sin(x)cos(jy)+cos(x)sin(jy)
=sin(x)(ey+e-y)/2+jcos(x)(ey-e-y)/2
即u=sin(x)(ey+e-y)/2,v=cos(x)(ey-e-y)/2。
(4) 复数z的余弦为
w=u+jv=cos(z)=cos(x+jy)
=cos(x)cos(jy)-sin(x)sin(jy)
=cos(x)(ey+e-y)/2-jsin(x)(ey-e-y)/2
即u=cos(x)(ey+e-y)/2,v=-sin(x)(ey-e-y)/2。
特别要指出的是,根据题目的要求,应允许给定复数z与计算结果w存放在同一个存储地址中,即在调用这些函数时,计算结果的实部与虚部仍然存放在给定复数的实部变量x与虚部变量y中。因此,在每一个函数中,当给定复数的实部x与虚部y还没有使用完,不能直接将计算结果赋给u或v,因为在这种情况下,函数中如果改变了u值,也即改变了x值;同样,函数中如果改变了v值,也即改变了y值。
13. 利用冒泡排序法对给定的单词序列进行排序。
具体要求:
(1) 编写一个函数,其功能是对由n个单词所构成的字符串序列按非递减顺序进行冒泡排序。其中单词序列中的各单词(即字符串)由长度为n的一维字符串指针数组中的各元素指向。
(2) 编写一个主函数,调用(1)中的函数,对下列单词序列进行排序:
zhang,gou,xu,zheng,mao,zhao,li,bai,qing
其中该单词序列中各单词以赋初值的方式用一维字符串指针数组的各元素指向。
(3) 在主函数中,要求先输出原序列,换行后再输出排序后的序列。输出时各单词之间用两个空格分隔。
方法说明:
使用字符串比较函数strcmp(),需要包含头文件string.h。
11.7 习题
1. 编写一个C程序,要求定义一个有关日期的结构体类型变量(包括年、月、日),从键盘为该变量中的各成员输入数据,然后再将输入的日期显示输出。
2. 建立一个学生情况登记表的表格空间(学生人数最多为20),包括学号、姓名、五门课程的成绩与总分。在主函数中调用以下函数实现指定的功能:
(1) 输入n个学生的数据(不包括总分)。其中n(≤20)在主函数中从键盘输入。
(2) 计算每个学生的总分。
(3) 按总分进行排序。
(4) 显示输出给定学号学生的所有信息。其中学号在主函数中从键盘输入。
3. 编写一个C程序,根据键盘输入的非负整数值,显示输出颜色的英文名称。
4. 编制一个C程序,定义一个长度为10的联合体类型数组。首先从键盘输入一个标志,标志值为0时表示输入五分制成绩(整型),标志值为1时表示输入百分制成绩(单精度实型)。然后从键盘输入10个成绩存放到数组中。最后输出这些成绩。
5. 编写一个C函数,功能是计算给定链表的长度。
6. 编写一个C函数,功能是逆转给定链表。
7. 设有两个有序线性单链表,头指针分别为ah与bh。编写一个C函数,将这两个有序链表合并为一个头指针为ch的有序链表。
8. 设有一个链表,其结点值均为正整数,且按值从大到小链接。编写一个C函数,将该链表分解为两个链表,其中一个链表中的结点值均为奇数,而另一个链表中的结点值均为偶数,且这两个链表均按值从小到大链接。
9. 设有一个链表,其结点值均为整数,且按绝对值从小到大链接。编写一个C函数,将此链表中的结点按值从小到大链接。
10. 设有一个链表,其结点值均为正整数。编写一个C函数,反复找出链表中结点值最小的结点。并输出该值,然后将该结点从链表中删除,直到链表空为止。
11. 给定学生成绩登记表如表11.4所示。编写一个C程序,用冒泡排序对该学生成绩表按成绩(grade)从低到高进行排序。
表11.4 学生成绩登记表
学号(num)
姓名(name)
成绩(grade)
02
Lin
92
03
Zhang
87
04
Zhao
72
05
Ma
91
09
Zhen
85
11
Wang
100
12
Li
86
13
Xu
83
16
Mao
78
17
Hao
95
20
Lu
82
21
Song
76
22
Wu
88
具体要求:
(1) 定义一个结构体数组表示学生成绩登记表,其中的每个元素依次存放表11.4中各学生的情况。
结构体类型为
struct student
{ int num;
char name[10];
int grade;
};
(2) 在程序中另外定义一个结构体指针数组,在排序前,其中每一个数组元素依次指向学生成绩登记表(为结构体类型数组)中的各学生情况。
(3) 在程序中,首先输出排序前的学生情况,然后输出排序后的结果。输出形式如表11.4所示,但不要表中的框线。
(4) 将冒泡排序的功能独立编写成一个函数。
方法说明:
在实际排序的过程中,并不需要交换学生成绩登记表中的各学生情况,而只需要交换另一指针数组中的各指针。因此,排序的最后结果,学生成绩登记表中各学生情况之间的存储顺序并没有改变,而只是按指针数组中各指针元素顺序指向的各学生情况是按成绩有序的。
12. 链表基本操作。
具体要求:
(1) 定义一个结构体数组表示学生成绩登记表,其中的每个元素依次存放表11.4中各学生的情况。
结构体类型为
struct student
{ int num;
char name[10];
int grade;
};
(2) 对于表11.4所示的学生成绩登记表,依次将每个学生的情况作为一个结点插入到链表的链头(即当前插入的结点将成为链表中的第一个结点)。初始时链表为空,即该链表的头指针为空。
每个学生情况结点结构的结构体类型为
struct stunode
{ int num;
char name[10];
int grade;
struct stunode *next;
};
(3) 当所有学生情况都插入到链表后,从链头开始,依次输出链表中的各结点值(即每个学生的情况)。输出格式如同表11.4所示,但不要表中的框线。
方法说明:
为了给每个学生情况的结点p动态分配存储空间,可以用如下语句:
p=(struct stunode *)malloc(sizeof(struct stunode));
其中p为结构体类型struct stunode的指针。
另外,为了使用函数malloc(),应该包含头文件stdlib.h。
13. 将表11.4所示的学生成绩登记表划分成三个子表,其中子表1登记的是成绩在90~100之间的学生情况,子表2登记的是成绩在80~89之间的学生情况,子表3登记的是成绩在70~79之间的学生情况。
具体要求:
(1) 定义一个结构体数组表示学生成绩登记表,其中的每个元素依次存放表11.4中各学生的情况。
结构体类型为
struct student
{ int num;
char name[10];
int grade;
};
(2) 划分成的三个子表均采用链表结构,链表中各结点的数据域存放学生情况在原登记表中的序号(即结构体数组元素的下标),而不是直接存放学生的成绩情况。即各链表结点的结构体类型为
struct stunode
{ struct student *data;
struct stunode *next;
};
(3) 最后输出原学生成绩登记表以及划分成的三个子表。输出格式如表11.4所示,但不要表中的框线。
方法说明:
划分子表的方法如下:
对于表11.4中的各学生成绩grade,计算
k=10-int(grade/10)
其中int()表示取整。根据k值将学生情况插入到相应的子表中:
若k=0或1,则插入到子表1中;
若k=2,则插入到子表2中;
若k=3,则插入到子表3中。
初始时各子表均为空。当需要将一个学生情况插入到某子表时,首先动态申请一个结点(struct stunode类型),将该学生情况在原表中的序号(元素下标)存放到结点的数据域中;然后将该结点链接到相应链表的链头。
12.4 习题
1. 编写一个C程序,首先从键盘输入20个双精度实数,并写入文本文件fd.dat中。然后将写入文件fdata.dat中的10个双精度实数显示输出。
2. 编写一个C程序,从键盘输入一个字符串(输入的字符串以“#”作为结束),将其中的小写字母全部转换成大写字母,并写入到文件upper.txt中。然后再从该文件中的内容读出并显示输出。
3. 编写一个C程序,主函数从命令行得到一个文件名,然后调用函数fgets( )从文件中读入一字符串存放到字符数组str中(字符个数最多为80个)。在主函数中输出字符串与该字符串的长度。fgets函数的格式为:char *fgets( char *string, int n, FILE *stream );
4. 编写一个C程序,将源文件拷贝到目的文件中。两个文件均为文本文件,文件名均由命令行给出,并且源文件名在前,目的文件名在后。
5. 设二进制文件student.dat中存放着学生信息,这些信息由以下结构体描述:
struct student
{ long int num;
char name[10];
int age;
char sex;
char sreciality[20];
char addr[40];
};
请编写一个C程序,显示输出学号在970101~970135之间的学生
展开阅读全文