第4章 数组
与指针有关的题目,请主动略过!
4.1内容概述
本章主要介绍了数值数组和字符数组的定义、初始化、元素引用和数组数据的输入与输出,字符数组实现字符串、字符串函数的实现与调用。指针数组与数组指针定义、元素引用。利用一维数组实现如挑数、排序、求和等实际应用问题。利用二维数组实现矩阵的应用问题。利用字符数组实现字符串的各种操作。本章知识结构如图4.1所示。
图4.1 第4章知识结构图
考核要求:掌握一维数组、二维数组、字符数组和 的定义和初始化;掌握数组元素存储地址计算;掌握数组元素的下标法、指针法引用;掌握字符数组与字符串的区别与联系;掌握有关字符串处理函数的使用方法;能利用一维数组、二维数组解决向量、矩阵等实际应用问题。
重点难点:本章的重点是一维数组、二维数组和字符数组的定义、初始化、元素引用,字符串处理函数的使用。本章的难点是字符串与字符数组的区别, 和数组元素的指针法引用。
核心考点:数组的定义、初始化和数组元素的引用方法,一维数组、二维数组和字符数组的实际应用,字符串的处理方法。
4.2 典型题解析
【例4.1】以下对一维数组a 的定义中正确的是( )。
A. char a(10);
B. int a[0..100];
C. int a[5];
D. int k=10;int a[k];
解析:一维数组定义的一般形式为:
类型标识符 数组名[常量表达式]
其中,常量表达式可以是任意类型,一般为算术表达式,其值表示数组元素的个数,即数组长度。
答案:C
数组
数值数组 定义 初始化
元素引用 数组元素输入和输出 字符数组 定义 初始化 元素引用 数组元素输入和输出
【例4.2】以下对一维数组的定义中不正确的是()。
A. double x[5]={2.0,4.0,6.0,8.0,10.0};
B. int y[5]={0,1,3,5,7,9};
C. char ch1[ ]={'1', '2', '3', '4', '5'};
D. char ch2[ ]={'\x10', '\xa', '\x8'};
解析:可以对一维数组的全部元素或部分元素赋初值。在对全部数组元素初始化时,数组长度可以省略。若数组长度没有省略,则初始化列表中值的个数不能超过数组的长度。
答案:B
【例4.3】以下对二维数组的定义中正确的是()。
A.int a[4][]={1,2,3,4,5,6}; B. int a[][3];
C.int a[][3]= {1,2,3,4,5,6}; D. int a[][]={{1,2,3},{4,5,6}};
解析:定义二维数组时,若按一维格式初始化,则第一维的长度可以省略,此时,系统可根据初始化列表中值的个数及第二维的长度计算出省略的第一维长度,但无论如何,第二维的长度不能省略。没有初始化时,每一维的长度都不能省略。
答案:C
【例4.4】假定一个int型变量占用两个字节,若有定义:int x[10]={0,2,4}; 则数组x在内存中所占字节数是()。
A. 3
B. 6
C. 10
D. 20
解析:一维数组在内存中所占的字节数为:数组长度×sizeof(元素类型)。
答案:D
【例4.5】以下程序的输出结果是()。
main()
{ int a[4][4]={{1,3,5},{2,4,6},{3,5,7}};
printf("%d%d%d%d\n",a[0][3],a[1][2],a[2][1],a[3][0]);
}
A. 0650
B. 1470
C. 5430
D. 输出值不定
解析:定义的数组a为4行4列,且前三行三列元素已初始化,根据C语法规定,未初始化的元素值为0。
答案:A
【例4.6】以下程序的输出结果是()。
main()
{ int m[][3]={1,4,7,2,5,8,3,6,9};int i,j,k=2;
for(i=0;i<3;i++){ printf("%d ",m[k][i]);}
}
A. 4 5 6
B. 2 5 8
C. 3 6 9
D. 7 8 9
解析:根据初始化列表中值的个数和第二维的长度,可求得第一维长度为3。第一行的元素值依次为1,4,7;第二行元素值依次为2,5,8;第三行元素值依次为3,6,9。循环执行三次,依次输出行标为2的三个元素,即第三行的3个元素。
答案:C
【例4.7】以下程序的输出结果是()。
main()
{ int b[3][3]={0,1,2,0,1,2,0,1,2},i,j,t=0;
for(i=0;i<3;i++)
for(j=i;j<=i;j++)
t=t+b[i][b[j][j]];
printf("%d\n",t);
}
A. 3
B. 4
C. 1
D. 9
解析:程序中,引用的b数组元素的行下标为循环变量i,列下标为数组元素b[j][j]。外层循环共进行3次,对于每次外循环,内层循环只执行一次(即j=i),所以变量t 的值为元素b[0][b[0][0]]、b[1][b[1][1]]、b[2][b[2][2]]的和。由于数组元素b[0][0]、b[1][1]、b[2][2]的值分别为0、1、2,所以t的值为:0+0+1+2=3。
答案:A
【例4.8】若有定义:int a[2][4];,则引用数组元素正确的是()。
A. a[0][3]
B. a[0][4]
C. a[2][2]
D. a[2][2+1]
解析:引用二维数组元素时,行下标范围为0~行数-1,列下标范围为0~列数-1。
答案:A
【例4.9】若有定义:int aa[8];,则不能代表数组元素aa[1]地址的是()。
A. &aa[0]+1
B. &aa[1]
C. &aa[0]++
D. aa+1
解析: &aa[1]、&aa[0]+1和aa+1都是数组元素aa[1]的地址。由于&aa[0]是地址值常量,不能进行自加、自减运算,所以选项C不能代表aa[1]地址。
答案:C
【例4.10】下列程序执行后的输出结果是()。
main()
{ int a[3][3], *p,i;p=&a[0][0];
for(i=0;i<9;i++) p[i]=i+1;
printf("%d \n",a[1][2]);
}
A. 3
B. 6
C. 9
D. 随机数
解析:二维数组的物理存储结构为一维,即按行序顺序存储在连续存储空间中。
本题中,p为指向数组元素的指针变量,初始时,p指向a[0][0]。通过指针p实现对对二维数组元素按行依次赋值。a[1][2]即p[5],其值6。
答案:B
【例4.16】若定义一个名为s且初值为"123"的字符数组,则下列定义错误的是()。
A.char s[]={’1','2','3','\0 '}; B.char s[]={"123"};
C.char s[]={"123\n"}; D.char s[4]={'1','2','3'};
解析:字符数组中所存字符中有’\0’时,字符数组才能作为字符串使用。选项A是用字符常量对字符数组初始化,且最后一个元素的值为字符串结束标记(’\0’),所以数组s中存放的就是字符串"123";选项D是用字符常量对部分元素初始化,根据 C语言的规定,系统为第四个元素赋初值为空值,即'\0',所以数组s中存放的也是字符串" 123"。选项B 是直接使用字符串"123"对字符数组初始化;选项C也是使用字符串初始化,但是字符串不是"123",而是"123\n",数组长度为5。
答案:C
【例4.17】下列程序的功能是输入N个实数,然后依次输出前l个实数和、前2个实数和、…、前N个实数和。填写程序中缺少的语句。
#define N 10
main()
{ float f[N],x=0.0;int i;
for(i=0;i scanf("%f",&f[i]); for(i=1;i<=N;i++) { ① ; printf("sum of NO %2d---------%f\n",i,x); } } 解析:分析程序可知,第一个循环实现数据的输入,第二个循环实现求和并输出,程序中缺少的是计算前i个实数和并存入变量x的语句。由于每次循环的x值都是在前一次循环的基础上作累加,即前i个实数和(x)等于前i-1个实数和(x)加上第i个实数f[i-1],因此,①处应填写:x=x+f[i-1];。 答案:x=x+f[i-l]; 或 x+=f[i-l]; 【例4.18】下面程序的功能是检查一个N×N矩阵是否对称(即判断是否所有的a[i][j]等于a[j][i])。请填空。 #define N 4 main() { int a[N][N]={1,2,3,4,2,2,5,6,3,5,3,7,4,6,7,4}; int i,j,found=0; for(j=0;j for( ① ;i if(a[i][j]!=a[j][i]) { ② ; break; } if(found) printf("No"); else printf("Yes"); } 解析:设置判断标志found,初始值为0。对于主对角线以上每个元素,分别与对称元素比较,若不相等,则将found置为1并结束比较。循环结束后,根据found的值确定是否对称。 答案:① i=j+1 ② found=1 【例4.19】编写程序,从一整型数组a的第一个元素开始,每三个元素求和并将和值存入到另一数组中(最后一组可以不足3个元素),最后输出所求的所有和值且每行输出5个值。 解析:用于存储和值的数组设为b,所有元素都初始化为0。从数组a的第一个元素开始,进行累加操作b[j]+=a[i],累加过程中,数组a的下标每自加3次,数组b的下标自加1次。重复此操作,直到数组a的所有元素累加完为止。输出时,每输出5个元素输出一次换行符"\n"。 #define N 20 #define M N/3+1 main() { int a[N],i,j,b[M]={0}; for(i=0;i for(i=0,j=0;i { b[j]+=a[i]; if((i+1)%3==0) j++; } if(N%3==0) j--; for(i=0;i<=j;i++) { printf("%d ",b[i]); if((i+1)%5==0) printf("\n"); } } 【例4.21】编写程序,将一维数组x中大于平均值的数据移至数组的前部,小于等于平均值的数据移至数组的后部。 解析:先计算一维数组x的平均值,然后将大于平均值的数据存入数组y的前部,小于等于平均值的数据存入数组y的后部,最后将数组y复制到数组x。 #include #define N 10 main() { int i,j; float av,y[N],x[N]; for(i=0;i av=0; for(i=0;i av/=N; for(i=j=0;i if(x[i]>av) { y[j++]=x[i];x[i]=-1;} for(i=0;i if(x[i]!=-1) y[j++]=x[i]; for(i=0;i { x[i]=y[i];printf("%5.2f ",x[i]);} } 【例4.22】已知一维整型数组a中的数已按由小到大的顺序排列,编写程序,删去一维数组中所有相同的数,使之只剩一个。 解析:从数组a的第二个元素开始,与前面保留的最后一个元素作比较,若不相等,则前移。重复此操作,直到数组a的最后一个元素为止。 #include #define N 20 main() { int a[N]={ 2,2,2,3,4,4,5,6,6,6,6,7,7,8,9,9,10,10,10,10}; int i,j; printf("The original data :\n"); for(i=0;i printf("%3d",a[i]); for(j=1,i=1;i if(a[j-1]!=a[i]) a[j++]=a[i]; printf("\n\nThe data after deleted :\n"); for(i=0;i printf("%3d",a[i]); } 【例4.23】编写程序,把从键盘输入的一个数字字符串转换为一个整数并输出。例如,若输入字符串“-1234”,则函数把它转换为整数值-1234。要求:不得调用C 语言提供的将字符串转换为整数的函数。 解析:设存放数字字符串的数组为s ,存放对应整型数的变量为n (初始值为0)。若字符串的第一个字符为’-’,则从第二个字符开始,否则从第一字符开始,利用公式n=n*10+s[i]-‘0’进行转换,直到’\0’为止。 #include #include main() { char s[10];long n=0; int i=0; printf("Enter a string:\n") ; gets(s); if(s[0]=='-') i++; while(s[i]) { n=n*10+s[i]-'0';i++;} if(s[0]=='-') n=-n; printf("%ld\n",n); } 【例4.25】编写程序,将二维数组a[N][M]中每个元素向右移一列,最右一列换到最左一列,移动后的数组存到另一个二维数组b 中,原数组保持不变。例如: 321654=a 213546=b 解析:将数组a 的最后一列元素存入数组b 的第1列中,再依次将数组a 的第i 列存入数组b 的第i+1列(0= #define N 3 #define M 3 main() { int a[N][M]={4,5,6,1,2,3,6,7,8},b[N][M],i,j; for(i=0;i b[i][0]=a[i][M-1]; for(i=0;i for(j=0;j b[j][i+1]=a[j][i]; for(i=0;i { for(j=0;j printf("%d ",b[i][j]); printf("\n"); } } 4.3 自测试题 1. 单项选择题 (1)以下定义语句中,错误的是( )。 A.int a[]={1,2}; B.char *a[3]; C.char s[10]="test"; D. int n=5,a[n]; (2)以下能正确定义二维数组的是( )。 A.int a[][3]; B.int a[][3]={2*3}; C.int a[][3]={}; D.int a[2][3]={{1},{2},{3,4}}; (3)以下程序的输出结果是( )。 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]); } (5)若有定义:int a[][3]={1,2,3,4,5,6,7,8}; ,则a数组的行数为( )。 A.3 B.2 C.无确定值 D.1 (6)下列描述中不正确的是 ( )。 A. 字符型数组中可以存放字符串 B. 可以对字符型串进行整体输入、输出 C. 可以对整型数组进行整体输入、输出 D. 不能在赋值语句中通过赋值运算符"="对字符型数组进行整体赋值 (7)运行下列程序的输出结果是()。 main() { int a[]={1,2,3,4,5},i,*p=a+2; printf("%d", p[1]-p[-1]); } A. 出错,因下标不能为负值 B. 2 C. 1 D. 3 (8)以下printf语句的输出结果是( )。 printf("%d\n", strlen("school")); A. 7 B. 6 C. 存在语法错误 D. 不定值 (9)若有语句:char s1[10], s2[10]="books";,则能将字符串books赋给数组s1的语句是( )。 A. s1="books"; B. strcpy(s1, s2); C. s1=s2; D. strcpy(s2, s1); (10)以下语句或语句组中,能正确进行字符串赋值的是( )。 A. char *sp; *sp="right!"; B. char s[10]; s="right!"; C. char s[10]; *s="right!"; D. char *sp="right!"; 2. 程序分析题(阅读程序,写出运行结果) (1) main() { int x[6],a=0,b,c=14; do { x[a]=c%2;a++;c=c/2;}while(c>=1); for(b=a-1;b>=0;b--) printf("%d ", x[b]); printf("\n"); } (2) main() { int i,n[6]={0}; for(i=1;i<=4;i++) { n[i]=n[i-1]*2+1; printf("%d ",n[i]); } } (3) #include #include main() { char c='a',t[]="you and me"; int n,k,j; n=strlen(t); for(k=0;k if(t[k]==c) {j=k;break;} else j=-1; printf("%d", j); } (4) #include main() { char str1[20]="China\0USA", str2[20]="Beijing"; int i, k, num; i=strlen(str1); k=strlen(str2); num=i printf("%d\n", num); } (5) #include main() { static int a[]={1,3,5,7}; int *p[3]={a+2,a+1,a}; int **q=p; printf("%d\n",*(p[0]+1)+**(q+2)); } 3. 程序填空题 (1)下面程序的功能是将字符数组a中下标值为偶数的元素从小到大排列,其它元素不变。请填空。 #include #include main() { char a[]="clanguage",t; int i,j,k; k=strlen(a); for(i=0;i<=k-2;i+=2) for(j=i+2;j if( ② ) {t=a[i];a[i]=a[j];a[j]=t;} puts(a);printf("\n"); } (3)下面程序的功能是把给定的字符按其矩阵格式读入数组str中,并输出行号与列号之和为3的数组元素。请填空。 main( ) { char str[4][3]={'A','b','C','d','E','f','G','h','I','j','K','l'}; int x,y,z; for(x=0;x<4;x++) for (y=0; ⑤ ;y++) { z=x+y; if( ⑥ ) printf("%c\n",str[x][y]); } } (4)下面程序的功能是输入一个3×3的实数矩阵,求两条对角线元素中各自的最大值。请填空。 main() { float s[3][3],max1,max2,x; int i,j; for(i=0;i<3;i++) for(j=0;j<3;j++) { scanf("%f",&x);s[i][j]=x;} max1= ⑦ ; for(i=1;i<3;i++) if(max1 max2= ⑧ ; if(max2 if(max2 printf("max1=%f\n",max1); printf("max2=%f\n",max2); } (5)下面程序的功能是利用数组计算并存储Fibonacci序列的前40项,每行输出4项。 请填空 main() { long int a[40]={1,1}; int i; for(i=2;i<40;i++) a[i]= ⑨ ; for(i=0;i<40;i++) { if( ⑩ ) printf("\n"); printf("%10ld",a[i]); } } 4. 程序设计题 (1)给定一维整型数组,输入数据并求第一个值为奇数元素之前的元素和。 (2)给定一维整型数组,输入数据并对前一半元素升序排序,对后一半元素降序排序。 (3)输入字符串并统计各数字字符出现的次数。 (4)给定N×N矩阵,输入矩阵元素并互换主次对角线元素值。 (5)给定二维数组a[M][N],输入数据并将元素按照行序存入到一维数组b中。 4.4 实验题目 (1)数组a中存放N个非0整数,编写程序,将数组a中的所有正数存放在数组的前面,负数存放在数组的后面。 (2)将数组a中的N个元素后移m位,移出的m位顺序存放在数组的前m位。 (4)将整型N×N矩阵主对角线元素进行升序排序。 (5)将4×4阶矩阵的4个最小值按升序存放在主对角线上。 (6)求N×N矩阵每行最大值的和。 (7)由键盘输入一个字符串,按照ASCII码由小到大的顺序排序,要求删除所输入的重复字符。如输入"ad2f3adjfeainzzzzv",则应输出"23adefijnvz"。 4.5 思考题 (1)定义二维数组时是否可以省略第一维长度?省略时系统如何计算长度? (2)定义一维数组与引用一维数组元素时,“[]”内数据的含义是什么? (3)若有定义:int a[3][4],(*q)[4]=a;,则如何利用指针变量q引用数组a的元素? (4)若有如下定义和语句: int a[3][4],*p[3]; p[0]=&a[0][0];p[1]=&a[1][0];p[2]=&a[2][0]; 则如何利用指针数组名p引用数组a的元素? (5)试说明下列两种定义方式的区别。 char a[3][8]={"gain","much","strong"}; char *a[3]={"gain","much","strong"}; 4.6 习题解答 1. 单项选择题(下列每小题有4个备选答案,将其中一个正确答案填到其后的括号内) (1)设有定义:int a[10],*p=a;,对数组元素的正确引用是()。 ① a[p] ② p[a] ③ *(p+2) ④ p+2 解答:a和p是地址,不可以用作数组元素的下标,所以①②错误,选项④为p之后两个元素的地址即等价于&a[2],选项③为元素a[2]。 答案:③ (2)若有如下定义,则不能表示数组a元素的表达式是()。 int a[10]={1,2,3,4,5,6,7,8,9,10},*p=a; ① *p ② a[10] ③ *a ④ a[p-a] 解答:因为p初值为a,所以选项①为元素a[0],选项③也为元素a[0],选项④为a[0],选项②元素下标超出下标界限(0~9)。 答案:② (3)若有如下定义,则值为3的表达式是()。 int a[10]={1,2,3,4,5,6,7,8,9,10},*p=a; ① p+=2,*(p++) ② p+=2,*++p ③ p+=3,*p++ ④ p+=2,++*p 解答:四个表达式都是逗号表达式,表达式的值为第二个式子的值,选项①的p从指向a[0]改变为指向a[2],因此表达式值为3,选项②的p指向a[2],计算*++p时指针指向a[3],表达式值为4,选项③的p指向a[3],表达式值为4,选项④的p指向a[2],计算++*p后a[2]元素值变为4。 答案:① (4)设有定义:char a[10]="ABCD",*p=a;,则*(p+4)的值是()。 ① "ABCD" ②’D’ ③’\0’ ④不确定 解答:数组所赋初值为串,数组a[4]及其后的六个元素值都为'\0',*(p+4)等价于*(a+4)即a[4]。 答案:③ (5)将p定义为指向含4个元素的一维数组的指针变量,正确语句为()。 ① int (*p)[4]; ② int *p[4]; ③ int p[4]; ④ int **p[4]; 解答:①定义p为指向含4个整型元素的一维数组的指针变量。②定义了一个有四个元素的指针数组,数组名为p,数组中的每一个元素都是指向整型变量的指针变量。③定义了一个有四个元素的整型数组,数组名为p。④定义了一个有四个元素的二级指针数组,数组名为p,数组中的每一个元素都是指向整型指针变量的指针变量。 答案:① (6)若有定义int a[3][4];,则输入其3行2列元素的正确语句为()。 ① scanf("%d",a[3,2]); ② scanf("%d",*(*(a+2)+1)) ③ scanf("%d",*(a+2)+1); ④ scanf("%d",*(a[2]+1)); 解答:输入3行2列元素的值,应使用其地址,即&a[2][1],或*(a+2)+1,或a[2]+1,所以③是正确的。 答案:③ (7)下面对指针变量的叙述,正确的是()。 ①指针变量可以加上一个指针变量。 ②可以把一个整形数赋给指针变量。 ③指针变量的值可以赋给指针变量。 ④指针变量不可以有空值,即该指针变量必须指向某一变量。 解答:指针变量加上一个指针变量没有意义,所以①是错误的。不能把一个整型数直接 赋给指针变量,因为类型不匹配,所以②是错误的。指针变量可以有空值(NULL),即不指向任何变量,所以④是错误的。指针变量的值可以赋给指针变量,同类型可以直接赋值,不同类型可通过强制类型转换,所以③是正确的。 答案:③ (8)设有定义:int a[10],*p=a+6,*q=a;,则下列运算哪种是错误的()。 ① p-q ② p+3 ③ p+q ④ p>q 解答:指向同一个数组的两个指针变量可以相减,其值是两个指针之间的元素个数。指向同一个数组的两个指针变量也可以比较,指向前面元素的指针“小于”指向后面元素的指针。指向数组元素的指针变量可以加减一个整型数c,加c后指向其后面的第c个元素,减c后指向其前面的第c个元素。但指向同一个数组的两个指针变量进行加法运算没有意义。 答案:③ (9)C语言中,数组名代表()。 ①数组全部元素的值②数组首地址 ③数组第一个元素的值④数组元素的个数 解答:C语言规定,数组名代表数组的首地址。 答案:② (10)若有如下定义,则值为4的表达式是()。 int a[12]={1,2,3,4,5,6,7,8,9,10,11,12}; char c=’a’,d,g; ① a[g-c] ② a[4] ③a[’d’-’c’] ④a[’d’-c] 解答:值为4的数组元素的下标为3,所以②是错误的,g-c的值不确定,’d’-’c’的值为1,只有’d’-c的值为3,所以④是正确的。 答案:④ (11)设有定义:char s[12]="string";则printf("%d",strlen(s));的输出结果是()。 ① 6 ② 7 ③ 11 ④ 12 解答:函数strlen()的功能是返回字符串中第一个’\0’之前的字符个数,所以输出结果为6。 答案:① (12)语句printf("%d",strlen("abs\no12\1\\"));的输出结果是()。 ① 11 ② 10 ③ 9 ④ 8 解答:字符串中的“\n”、“\1”和“\\”都是转义字符,都表示一个字符,所以字符串中的字符个数为9。 答案:③ (13)设有定义:int t[3][2];,能正确表示t数组元素地址的表达式是()。 ① &t[3][2] ② t[3] ③ t[1] ④ *t[2] 解答:C语言中,数组元素的下标从0开始,所以①和②是错误的,④表示数组元素a[2][0],③表示第二行的首地址,所以③是正确的。 答案:③ (14)语句strcat(strcpy(str1,str2),str3);的功能是()。 ①将字符串str1复制到字符串str2中后再连接到字符串str3之后。 ②将字符串str1连接到字符串str2中后再复制到字符串str3之后。 ③将字符串str2复制到字符串str1后再将字符串str3连接到字符串str1之后。 ④将字符串str2连接到字符串str1后再将字符串str1复制到字符串str3中。 解答:先执行strcpy(str1,str2),即将字符串str2复制到字符串str1中,再执行 strcat(str1,str3),即将字符串str3连接到字符串str1之后。 答案:③ (15)若有如下定义,则正确的叙述为()。 char x[]="abcdefg"; char y[]={’a’,’b’,’c’,’d’,’e’,’f’,’g’}; ①数组x和数组y等价②数组x和数组y的长度相同 ③数组x的长度大于数组y的长度④数组y的长度大于数组x的长度 解答:char y[]={’a’,’b’,’c’,’d’,’e’,’f’,’g’,’\0’};等价于:char x[]="abcdefg";,所以③是正确的。 答案:③ 2.程序分析题 (1)下列程序的运行结果是 main() { int a[3][3]={{1,2},{3,4},{5,6}}; int i,j,s=0; for(i=0;i<3;i++) for(j=0;j<=i;j++) s+=a[i][j]; printf("%d\n",s); } 解答:此程序完成的功能是计算3×3矩阵的下三角阵(包括主对角线元素)元素和,运行结果是1+3+4+5+6,即19。 答案:19 (2)下列程序的运行结果是 main() { int i,j,k,n[3]; for(i=0;i<3;i++) n[i]=0; k=2; for(i=0;i for(j=0;j n[j]=n[i]+1; printf("%d\n",n[1]); } 解答:当i=0时,n[0]=n[0]+1=1,n[1]=n[0]+1=2。 当i=1时,n[0]=n[1]+1=3,n[1]=n[1]+1=3。 答案:3 (3)下列程序的运行结果是 main() { int a[]={2,4,6,8,10}; int y=1,x,*p; p=&a[1]; for(x=0;x<3;x++) y+=*(p+x); printf("%d\n",y); } 解答:程序的功能是把数组a中下标为1、2和3的元素值累加到变量y上,即: y=1+4+6+8=19。 答案:19 (4)下列程序的运行结果是 main() { int i,c; char num[][4]={"CDEF","ACBD"}; for(i=0;i<4;i++) { c=num[0][i]+num[1][i]-2*’A’; printf("%3d",c); } } 解答:程序的功能是从左向右依次输出两个字符串对应字符的ASCII码之和与130的差值。 答案:2 5 5 8 (5)下列程序的运行结果是 main() { char a[]="*****"; int i,j,k; for(i=0;i<5;i++) { printf("\n"); for(j=0;j for(k=0;k<5;k++) printf("%c",a[k]); } } 解答:此程序的功能是输出5行“*”号,每行有5个“*”,且从上到下每行向右挫一列。 答案: ***** ***** ***** ***** ***** (6)下列程序的功能是 main() { int i,a[10],*p=&a[9]; for(i=0;i<10;i++) scanf("%d",&a[i]); for(;p>=a;p--) printf("%3d",*p); } 答案:该程序把从键盘输入的10个整型数按相反的顺序输出。 (7)下列程序的运行结果是 main() { char ch[2][5]={"6937","8254"},*p[2]; int i,j,s; for(i=0;i<2;i++) p[i]=ch[i]; for(i=0;i<2;i++) { s=0; for(j=0;ch[i][j]!=’\0’;j++) s=s*10+ch[i][j]-’0’; printf("%5d",s); } } 解答:程序的功能是把数字串转换成对应的数值。 答案:6937 8254 (8)下列程序的运行结果是 #include "stdio.h" main() { int i,k,a[10],p[3]; k=5; for ( i=0;i<10;i++) a[i]=i; for(i=0;i<3;i++) p[i]=a[i*(i+1)]; for( i=0;i<3;i++) k+=p[i]*2; printf("%d\n",k); } 解答:由于k=5+(p[0]+p[1]+p[2])*2,且p[i]=a[i*(i+1)]=i*(i+1),所以k的值为5+(0+2+6)*2=21。 答案:21 (9)下列程序的运行结果是 #include "stdio.h" main( ) { int a=2,*p,**pp; pp=&p; p=&a; a++; printf("%d,%d,%d\n",a,*p,**pp); } 解答:由于p指向a,pp又指向p,所以a、*p和**pp等价,其值都为3。 答案:3,3,3 (10)下列程序的运行结果是 main( ) { int a[6],i; for(i=0;i<6;i++) { a[i]=9*(i-2+4*(i>3))%5; printf("%2d",a[i]); } } 解答:程序的功能是:i的值从0到5,依次输出表达式9*(i-2+4*(i>3))%5的值。答案:-3 –4 0 4 4 3 3. 程序填空题(在下列程序的处填上正确的内容,使程序完整) (1)下列程序的功能是输出数组s中最大元素的下标。 main() { int k,i; int s[]={3,-8,7,2,-1,4}; for(i=0,k=i;i<6;i++) if(s[i]>s[k]) ① ; printf("k=%d\n",k); } 解答:程序输出的是最大元素的下标,所以,应将i值赋给k,即k=i。 答案:①k=i (2)下列程序的功能是将一个字符串str的内容颠倒过来。 #include "string.h" main() { int i,j,k; char str[]="1234567"; for(i=0,j= ② ;i { k=str[i];str[i]=str[j];str[j]=k;} printf("%s\n",str); } 解答:由于C语言中数组元素的下标从0开始,所以j的值应为字符串长度减1,即strlen(str)-1。 答案:② strlen(str)-1 (3)下列程序的功能是把输入的十进制长整型数以十六进制数的形式输出。 main() { char b[]="0123456789ABCDEF"; int c[64],d,i=0,base=16; long n; scanf("%ld",&n); do {c[i]= ③ ;i++;n=n/base; }while(n!=0); for(--i;i>=0;--i) { d=c[i];printf("%c",b[d]);} } 解答:进制转换的算法是除以基数取余,所以应填n%base。 答案:③ n%base (4)下列程序的功能是从键盘输入若干个字符(以回车键作为结束)组成一个字符串存入一个字符数组,然后输出该数组中的字符串。 #include "stdio.h" main() { char str[81],*ptr; int i; for(i=0;i<80;i++) { str[i]=getchar(); if(str[i]==’\n’) break; } str[i]= ④ ; ptr=str; while(*ptr) putchar( ⑤ ); } 解答:根据while(*ptr)可知,字符串末尾应有’\0’,所以第一个空应填’\0’。当ptr 所指向的字符不为’\0’时,将其输出,并且使ptr指向下一个字符,所以第二个空应填*ptr++。 答案:④’\0’⑤ *ptr++ (5)下列程序的功能是将数组a的元素按行求和并存储到数组s中。 main() { int s[3]={0}; int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; int i,j; for(i=0;i<3;i++) { for(j=0;j<4;j++) ⑥ ; printf("%d\n",s[i]); } } 解答:根据题意,应将第i行累加到数组元素s[i]中。程序中的外循环次数是行数,内循环次数是列数,所以应填s[i]+=a[i][j](或s[i]=s[i]+a[i][j])。 答案:⑥ s[i]+=a[i][j](或s[i]=s[i]+a[i][j]) 4. 程序改错题(下列每小题有一个错误,找出并改正) (1)下列程序的功能是输入一个字符串,然后再输出。 main() { char a[20]; int i=0; scanf("%s",&a); while(a[i]) printf("%c",a[i++]); } 解答:使用scanf()函数时,输入项是地址,数组名本身就是地址,对数组名进行取地址运算没有意义。 答案:错误行:scanf("%s",&a); 修改为:scanf("%s",a); (2)下列程序的功能是复制字符串a 到b中。 main() { char *str1=a,*str2,a[20]="abcde",b[20]; str2=b; while(*str2++=*str1++); } 解答:程序中用数组名a初始化指针变量str1,但此时数组a还没有定义,C语言规定,变量或数组必须先定义后使用,所以,必须先定义数组a,然后再定义指针变量str1,并用a 对其初始化。 错误行:char *str1=a,*str2,a[20]="abcde",b[20]; 修改为:char a[20]="abcde",*str1=a,*str2, b[20]; (3)下列程序的功能是统计字符串中空格数。 #include "stdio.h" main() { int num=0; char a[81],*str=a,ch; gets(a); while((ch=*str++)!=’\0’) if(ch=’’) num++; printf("num=%d\n",num); } 解答:“=”是赋值运算符,程序中进行条件判断应使用关系运算符“==”。 答案:错误行:if(ch=’’) num++; 修改为:if(ch==’’) num++; (4)下列程序的功能是将字符串str中小写字母的个数、大写字母的个数和数字字符的个数分别存入a[0]、a[1]和a[2]中。 #include "stdio.h" main() { char str[80]; int a[3],i=0; gets(str); for(;str[i]!=’\0’;i++) if(str[i]>=’a’&&str[i]<=’z’) a[0]++; else if(str[i]>=’A’&&str[i]<=’Z’) a[1]++; else if(str[i]>=’0’&&str[i]<=’9’) a[2]++; for(i=0;i<3;i++) printf("%4d\n",a[i]); } 解答:数组a在定义时没有初始化,所以数组元素的初始值是随机的,因此,得到的统计结果不正确。 答案:错误行:int a[3],i=0; 修改为:int a[3]={0},i=0; (5)下列程序的功能是计算3×3矩阵的主对角线元素之和。 main() { int i,a[3][3]={1,2,3,4,5,6,7,8,9},sum=0; for(i=1;i<=3;i++) sum+=a[i][i]; printf("sum=%d\n",sum); } 解答:C语言中数组元素的下标是从0开始的,所以循环变量i的取值应该是0到2。 答案: 错误行:将语句for(i=1;i<=3;i++) sum+=a[i][i]; 修改为:for(i=0;i<3;i++) sum+=a[i][i]; 5. 程序设计题 (1)输入10个整型数存入一维数组,输出值和下标都为奇数的元素个数。 main() { int a[10],i,num=0; printf("enter array a:\n"); for(i=0;i<10;i++) scanf("%d",&a[i]); for(i=0;i<10;i++) if(i%2==1&&a[i]%2==1) num++; printf("num=%d\n",num); } (2)从键盘输入任意10个数并存放到数组中,然后计算它们的平均值,找出其中的最大数和最小数,并显示结果。 解答: main() { float a[10],ave=0,max,min; int i; printf("enter array a:\n"); for(i=0;i<10;i++) scanf("%f",&a[i]); max=a[0];min=a[0]; for(i=0;i<10;i++) { ave+=a[i];