第六章 利用数组处理批量数据
1、数组的定义
类型符 数组名[常量表达式] int a[10]
数组下标实从0开始的,下标表示数组长度。
2、通过下标引用数组元素
数组名[下标]
下标可以是整型常量,也可以是整型表达式
3、引用数组元素。利用循环结构把数值0-9赋值给数组元素a[0]~a[9],然后按逆序输出各元素的值
#include <stdio.h>
int main()
{
int i,a[10];
for(i=0;i<=9;i++)
{
a[i]=i;
}
for(i=9;i>=0;i--)
{
printf("%d",a[i]);
}
printf("\n");
return 0;
}
4、一位数组的初始化
int a[5]={0,1,2,3,5}; // 定义长度为4的数组并初始化
int a[]={1,2,3,4,5}; // 长度根据后面元素个数自行定义
int a[10]={0,1,2,3}; // 长度多于实际元素个数,后面补0
5、用数组处理斐波那契数列问题,输出数列中前20个数。
#include <stdio.h>
int main()
{
int i;
int f[20]={1,1}; // 第一、第二项
for(i=2;i<20;i++) // 求出f[2]到f[19]的值,这里i只是下标变量
{
f[i]=f[i-2]+f[i-1]; // 第三项是第一项与第二项的和
}
for(i=0;i<20;i++) // 遍历数组
{
if(i%5==0) // 每5个元素打印一行
{
printf("\n");
}
printf("%12d",f[i]);
}
printf("\n");
return 0;
}
对比之前循环章节来分析,数组可以按需输出第几个元素。
6、冒泡排序:假如有n个人,各人年龄不同,希望按年龄将他们从小到大排列
#include <stdio.h>
int main()
{ int a[10];
int i,j,t;
printf("Please enter 10 numbers :\n");
for(i=0;i<10;i++) // 要输入多个数
{
scanf("%d",&a[i]);
}
for(j=0;j<9;j++) // j是由多少趟:排列数字个数-1
{
for(i=0;i<9-j;i++) // 每一趟中要比较多少次 9-j
{
if(a[i]>a[i+1])
{
t=a[i];
a[i]=a[i+1];
a[i+1]=t;
}
}
}
printf("The sorted numbers:\n");
for(i=0;i<10;i++)
{
printf("%2d\t",a[i]);
}
printf("\n");
return 0;
}
7、二维数组
(1)定义一个二维数组
类型名 数组名[常量表达式][常量表达式]
float a[3][4],b[5][10]; // a为3×4列的数组
(2)引用二维数组
a[1][2]=b[1][2]/2 //数组元素可以出现在表达式中,也可以被赋值
(3)二维数组的初始化
1)分行赋初值
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
2)按数组排列赋值
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
3)部分赋值
int a[3][4]={{1},{5},{9}} // 只对各行的第一个元素赋值
int a[3][4]={{1},{0,6},{0,0,11}}; // 没有赋值的自动补零
int a[3][4]={{1},{},{9}}; // 第二行不赋值
4)一维的下标可以省略,但是二维不能省略
int a[][4]={{0,0,3},{},{0,10}};
8、将一个二维数组a的行和列的元素互换(即行列转置),存到另一个二维数组b中。
#include <stdio.h>
int main()
{ int i,j;
int a[2][3]={{1,2,3},{5,6,7}}; // 定义数组a并赋值
int b[3][2]; // 定义数组b长度,不赋值
printf("array a:\n");
for(i=0;i<2;i++) // i控制行数的变化
{
for(j=0;j<3;j++) // j控制列数的变化
{
printf("%3d",a[i][j]); // 输出a数组中i行j列元素
b[j][i]=a[i][j]; // 将a数组i行j列元素,赋值给b数组j行i列元素
}
printf("\n");
}
printf("array b:\n");
for(i=0;i<3;i++) // 遍历输出b数组的值
{
for(j=0;j<2;j++)
{
printf("%5d",b[i][j]); // 此处的i,j表示的是b数组的几行几列 即 j=i
}
printf("\n");
}
return 0;
}
9、有一个班5个学生,已知每个学生有5门成绩,要求输出平均成绩最高的学生的成绩以及该学生的序号
#include <stdio.h>
int main()
{
int i,j,sum,num=5; // i为行数,j为列数,sum为每行的总分
int max=0,max_i; // 假设该行最大max为0,max_i用于存储最大平均成绩的下标
int average[5]; // average数组用于存放每个(行)学生的平均成绩
float score[5][5]={{71,81,91,80,70},{72,82,92,80,70},{90,90,90,90,90},{62,82,78,90,81},{82,71,81,78,67}};
for(i=0;i<5;i++)
{
sum=0; // 计算每一个科成绩的时候,sum都从零开始
for(j=0;j<5;j++)
{
sum=sum+score[i][j];
}
printf("第%d个学生的总分:%10d\n",i,sum);
average[i]=sum/num;
printf("第%d个学生的平均分:%8d\n",i,average[i]);
printf("\n");
}
for(i=0;i<5;i++)
{
if(average[i]>max)
{
max=average[i];max_i=i;
}
}
printf("_____________________________\n");
printf("第%d个的学生的平均成绩最高:%d\n\n",max_i,max);
return 0;
}
10、字符数组
(1)定义字符数组并初始化
char c[5];
c[0]='C';c[1]='h';c[2]='i';c[3]='n';c[4]='a';
char c[5]={'C','h','i','n','a'};
PS:字符数组和普通数组也可以根据实际元素个数自行按需定义长度
(2)引用字符数组
#include <stdio.h>
int main()
{
int i,j;
char diamond[5][5]={{' ',' ','*',' ',' '},{' ','*',' ','*',' '},{'*',' ',' ',' ','*'},{' ','*',' ','*',' '},{' ',' ','*',' ',' '}};
for(i=0;i<5;i++) // 控制行
{
for(j=0;j<5;j++) // 控制列
{
printf("%c",diamond[i][j]);
}
printf("\n");
}
return 0;
}
PS:C语言中,将字符串作为字符数组来处理,如果字符数组的定义的长度,而实际元素没有这么多,编译系统会自动加一个"\0" 作为 结束符 。
(3)用字符串常量来初始化数组
char c[]="I am happy"; // 用字符常量初始字符数组,后面自动补'\0',这里数组长度为11.
char b[]={'I',' ','a','m',' ','h','a','p','p','y'}; // 单个字符赋值为数组,数组长度为10
(4)字符数组的格式输入输出
1)逐个输入输出。格式声明用 "%c"
2)整个字符串一次输入输出。格式声明用 "%s"。
char c[]="I am happy";
printf("%s\n",c); // 这样就不用for循环逐个遍历打印啦!
3)注意的几点:
① 输出字符不包括结束符"\0";
② 不管字符数组多长,遇到"\0"就结束,不管结束符有多少个,遇到第一个就结束;
③ 未赋值元素自动补"\0";
④ 如果scanf函数的输入项是字符数组名,则不用加地址符"&",因为数组名就代表起始地址,用printf函数输出也同理;
(5)字符串处理函数

gets(输入)、puts(输出)、strcat(拼接)、strcpy(复制)、strcmp(比较)、strlen(长度)、strlwr(大转小)、strupr(小转大)
11、字符数组应用举例
1)有3个字符串,要求找出其中“最大”者
#include <stdio.h>
#include <string.h>
int main()
{
char string[20]; // 存放“最大”字符串
char str[3][20];
int i;
for(i=0;i<3;i++)
{
gets(str[i]); // 读入三个字符串,并存放在字符数组str中
}
if(strcmp(str[0],str[1])>0) // 比较串0和串1
{
strcpy(string,str[0]); // 如果串0比串1大,则存放串0在string中
}else
{
strcpy(string,str[1]); // 否则存放串1
}
if(strcmp(str[2],string)>0) // 再拿串3和string的字符串比较
{
strcpy(string,str[2]); // 如果比里面的大,则覆盖
}
printf("The largest string is:\n%s\n",string);
return 0;
}
2)输入一行字符,统计其中有多少个单词,单词之间用空格分隔开
#include <stdio.h>
#include <string.h>
int main()
{
char string[81];
int i,num=0,word=0; // 开始时,单词数为0,未出现单词
char c; // c用来存放当前需要判断的字符
gets(string); // 读入一个字符串,存放在string数组中
for(i=0;(c=string[i])!='\0';i++) // 从第一个字符串,到最后一个字符串
{
if(c==' ') // 如果当前字符是空格,则使word置0
{
word=0;
}else if(word==0) // 若当前字符不是空格,而且前一个字符是空格
{
word=1; // 使word置1
num++; // 使num加1
}
}
printf("There are %d words in the line.\n",num);
return 0;
}
提高部分
1、gets函数(读入字符串函数)
char str[20];
gets(str); // 从键盘输入一个字符串,存放在str数组中
2、pust函数(输出字符串函数)
char str[]={"happy!"};
puts(str); // 输出str字符串在屏幕,实际和printf差不多
3、strcat(字符串连接函数)
char str1[30]={"People's of Republic"};
char str2[]={"China"};
printf("%s",strcat(str1,str2)); // 将字符串2拼接到字符串1
4、strcpy和(整个字符串)
strcpy(字符数组,字符串2)
char str1[10]='',str2[]={"China"};
strcpy(str1,str2); // 将字符串2复制给字符串1
5、strncpy(复制前几个字符)
strncpy(str1,str2,2);
6、strcmpy函数(字符串比较函数)
strcpy(字符串1,字符串2)
- 如果字符串1=字符串2,则函数值为0
- 如果字符串1>字符串2,则函数值为一个正整数
- 如果字符串1<字符串2,则函数值为负整数
if(strcmp(str1,str2)>0)
printf("yes");
7、strlen函数(测字符串长度函数)
char str[10]={"China"};
printf("%d",strlen(str));
8、strlwr函数(转换为小写) lwr
9、strupr函数(转换为大写) upr
习题部分
1、一个班有10个学生的成绩,要求输入这10个学生的成绩,然后求出他们的平均分。
#include <stdio.h>
int main()
{
int a[10];
int i,sum=0,average;
printf("Please enter student's scores:\n");
for(i=0;i<10;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
average=sum/10;
printf("The average score is %d\n",average);
return 0;
}
2、在上题基础上求出平均成绩最高的课程(以课程序号表示)及其成绩
#include <stdio.h>
int main()
{
int a[3][5]; // 存放学生成绩,行为科目,列学生
int average[3]; // 用来存放每科的平均成绩
int i,j,max,max_s;
printf("Please enter student's scores:\n");
for(j=0;j<3;j++) // 控制行
{
int sum=0; // 每次单科成绩总分都是从0算起的
for(i=0;i<5;i++) // 控制列
{
scanf("%d",&a[j][i]);
sum=sum+a[j][i]; // 也就是按行加
}
average[j]=sum/5; // 一行统计完之后计算该行平均成绩,并赋值给average数组
printf("The average score is %d\n",average[j]);
}
printf("_________________\n");
for(j=0;j<3;j++) // 遍历平均分数组进行比较
{
if(average[j]>average[j+1])
{
max=average[j];
max_s=j; // 如果该行最大,则返回行数(课程序号)
}else
{
max=average[j+1];
}
}
printf("最大平均分为:%d\n该课程的序号为:%d\n",max,max_s);
return 0;
} // 此程序有bug哈哈哈哈
3、已知一个班10个学生的成绩,存放在一个一维数组中,要求找其中成绩最高的学生的成绩和该学生的序号
#include <stdio.h>
int main()
{
int score[10]={70,80,60,60,70,90,80,100,90,80}; // 存放10个学生的成绩
int j,max=0,max_p; // 假设最大值是 0
for(j=0;j<10;j++)
{
if(score[j]>max)
{
max_p=j+1;
max=score[j];
}
}
printf("最大平均分为:%d\n该课程的序号为:%d\n",max,max_p);
return 0;
}
4、有3个学生,上4门课,要求输入全部学生的各课成绩,并分别求出每门的平均成绩
#include <stdio.h>
int main()
{
int score[3][4];
int average[3];
int i,j;
printf("请输入第1门课程学生的成绩:\n");
for(i=0;i<3;i++)
{
int sum=0;
for(j=0;j<4;j++)
{
scanf("%d",&score[i][j]);
sum+=score[i][j];
}
average[i]=sum/4;
printf("请输入第%d门课程学生的成绩:\n",i+2);
}
printf("________________________________\n");
for(i=0;i<3;i++)
{
printf("第%d门课程的平均分为:%d\n",i+1,average[i]);
}
return 0;
}
5、已知5个学生的4门课成绩,要求求每个学生的平均成绩,然后对平均成绩从高到低将个学生的成绩记录排序(成绩最高的学生排在数组最前面的行,成绩最低的学生排在数组最后面的行)。
/* 答案不正确的哇*/ #include <stdio.h> int main() { int score[5][4]={{60,60,70,70},{80,80,85,70},{80,90,90,90},{60,60,70,60},{80,80,80,90}}; int average[5]; int i,j,sum,temp; for(i=0;i<5;i++) { sum=0; for(j=0;j<4;j++) { printf("%d\t",score[i][j]); sum+=score[i][j]; // printf("%d",sum); } average[i]=sum/4; printf("average:%d",average[i]); printf("\n"); } // i-1; for(i=0;i<4;i++) { for(j=0;j<4-i;j++) { if(average[j]<average[j+1]) { temp=average[j]; average[j]=average[j+1]; average[j+1]=temp; } } } printf("\n"); for(i=0;i<5;i++) { printf("%d\t",average[i]); } printf("\n"); return 0; }
6、将一个数组中的值按照逆序重新存放。
1)用两个数组实现
#include <stdio.h>
int main()
{
int i;
int t[5];
int a[5]={43,54,65,74,87};
for(i=0;i<5;i++)
{
t[i]=a[4-i];
a[i]=t[i];
printf("%d\t",a[i]);
}
return 0;
}
2)用一个临时变量实现
#include <stdio.h>
#define N 5
int main()
{
int a[N],i,temp;
printf("enter array a:\n");
for (i=0;i<N;i++)
scanf("%d",&a[i]);
printf("array a:\n");
for (i=0;i<N;i++)
printf("%4d",a[i]);
for (i=0;i<N/2;i++) //循环的作用是将对称的元素的值互换
{
temp=a[i]; // 每次循环将a[i]的值存储起来
a[i]=a[N-i-1]; // a[i]的位置对着数组倒数的元素,关系是假设有5个元素,则a[0]---a[4],a[1]---a[3]
a[N-i-1]=temp; // 后面的位置代回存储在temp的a[i]
}
printf("\nNow,array a:\n");
for (i=0;i<N;i++)
printf("%4d",a[i]);
printf("\n");
7、打印下面图案
*****
*****
*****
*****
*****
#include <stdio.h> int main() { int i,j; char c[]={"*"}; for(i=0;i<5;i++) { for(j=0;j<i+1;j++) { printf(" "); } for(j=0;j<5;j++) { printf("%s",c); } printf("\n"); } return 0; }
8、有一篇短文,共有3行文字,每行有80个字符。想统计其中英文大写字母,小写字母,数字、空格及其他字符各有多少个。
#include <stdio.h> int main() { int i,j; int E=0,e=0,n=0,s=0,o=0; char a[3][80]={ {"Mr.Johnson had never been up in an aerophane before and he had read a lot about"}, {" air accidents, so one day when a friend offered to take him for a ride in his "}, {"won small phane, Mr. Johnson was very worried about accepting. Finally, 1234 56"}}; for(i=0;i<3;i++) { for(j=0;j<80;j++) { printf("%c",a[i][j]); if(a[i][j]>64&&a[i][j]<91) { E++; } else if(a[i][j]>96&&a[i][j]<123) { e++; } else if(a[i][j]>47&&a[i][j]<58) { n++; }else if(a[i][j]==' ') { s++; }else if(a[i][j]!='\0') // 其他情况就是不是数组结尾时,统计其他字符个数 { o++; } } printf("\n"); } printf("\n"); printf("大写个数:%5d\n小写个数:%5d\n数字个数:%5d\n空格个数:%5d\n其他个数:%5d\n",E,e,n,s,o); return 0; }
9、有一行电文,已按照下面的规律译成密码,要求求密码原文
A—>Z a—>z
B—>Y b—>y
C—>X c—>x
... ...
#include <stdio.h>
int main()
{
char str[20];
gets(str);
printf("Key: ");
puts(str);
int i;
for(i=0;i<=20;i++)
{
if(str[i]>='A' && str[i]<='Z')
str[i]=65+90-str[i];
if(str[i]>='a' && str[i]<='z')
str[i]=97+122-str[i];
}
printf("Text: ");
puts(str);
return 0;
}
#include<stdio.h>
#include <string.h>
int main()
{
char s[1024] = {0};
scanf("%s", s);
int len = strlen(s) // 转换
for (int i = 0; i < len; ++i)
{
// 如果是小写字母(大写字母出来类似):
// 1. 先用s[i] - 'a'计算出s[i]是26个字母中从前往后数的第几个
// 2. 再用26 - (s[i]- 'a') - 1 转换为26个字母中从后往前数的第几个
// 3. 在2的结果上加上'a',即转换为对应从后往前的第几个字母
if (s[i] >= 'a' && s[i] <= 'z')
s[i] = 'a' + 26 - (s[i]-'a')-1;
else if (s[i] >= 'A' && s[i] <= 'Z')
s[i] = 'A' + 26 - (s[i] - 'A')-1;
}
printf("%s\n", s);
return 0;
}
10、编写一个程序,将了两个字符串连接起来,(1)用strrcat函数,(2)不用strcat函数
(1)用strrcat函数
#include<stdio.h>
#include <string.h>
int main()
{
char a[20]={"Hello "};
char b[]={"World!"};
printf("%s\n",strcat(a,b));
return 0;
}
(2)不用strcat函数
#include<stdio.h>
#include <string.h>
int main()
{
int i,len_a,len_b;
char a[20]={"Hello "};
char b[]={"World!"};
len_a=strlen(a);
len_b=strlen(b);
for(i=0;i<len_b;i++)
{
a[len_a+i]=b[i];
}
puts(a);
printf("%d,%d\n",len_a,len_b);
return 0;
}

浙公网安备 33010602011771号