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+1]=a[j] j=j-1 输出a[k], k=0, 1, ?, 99
15. 利用高斯(Gauss)消去法求解线性代数方程组。 具体要求:
(1) 编写一个用高斯(列选主元)消去法求解给定线性代数方程组的函数 gauss(a, b, x)
其中a为系数矩阵,b为常数向量,x为解向量。
(2) 编写一个主函数,调用(1)中的函数求解下列线性代数方程组: ?1.1161x1?0.1254x2?0.1397x3?0.1490x4?0.1582x?1.1675x?0.1768x?0.1871x?1234??0.2368x1?0.2471x2?0.2568x3?1.2671x4??0.1968x1?0.2071x2?1.2168x3?0.2271x4?1.5471?1.6471
?1.8471?1.7471其中系数矩阵与常数向量利用初始化赋初值。
(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
xi?bi?j?i?1?anijxj,i=n-1,?,2,1
列选主元的基本思想是在变换到第k步时,从第k列的akk以下(包括akk)的所有元素中选出绝对值最大者,然后通过行交换将它交换到akk的位置上。由于交换系数矩阵中的两行(包括交换常数向量中的两个相应元素),只相当于两个方程的位置被交换了,因此,列选主元不影响求解结果。
最后需要说明的是,在C语言中,数组的下标是从0开始的,不是从1开始的。另外,注意在函数gauss()中要将二维数组的下标转换成一维数组的下标。
10.8 习题
1. 阅读下列C程序: (1)
#include
{ int a[4][3]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; int (*ptr)[3]=a, *p=a[0];
printf(\}
输出结果为()。 (2)
#include
{ int a[5]={2, 4, 6, 8, 10};
int *p=a, **k, z;
k=&p; z=*p; p=p+1; z=z + **k; printf(\ }
输出结果为()。 (3)
#include
voidast(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(\ }
输出结果为()。
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函数intstr_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) =lnx2?y2+jArctg(y/x) 即u=lnx2?y2,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的一维字符串指针数组中的各元素指向。