第八章 数组
1.C语言中数组的下标都是从0开始,数组名代表数组的首地址;
2.定义数组时,不能使用变量定义数组的大小,而只能用整型常量;
3.一维数组的定义格式:类型 数组名[元素个数];
二维数组的定义格式:类型 数组名[第一维长度][第二维长度];(i行j列)
4.一维数组初始化时,可将元素初值放在=后面用一对大括号括起来的初始化列表中;
二维数组初始化时,可按元素初始化,也可按行初始化;
5.一维数组初始化注意:
①初始化列表中提供的初值个数不能多于数组元素的个数;
②若省略对数组长度的声明,初始化列表中的初值个数就是数组的大小;
③当只给部分数组元素赋初值时,必须声明数组的长度;
二维数组初始化注意:
①当初始化列表给出全部元素初值时,第一维长度声明可省略,系统将按初值个数定义数组大小;
②按行初始化时,即使初始化列表中提供初值个数少于数组元素个数,第一维长度声明也可省略,后面补0;
③数组第二维长度声明永远不能省略,即必须要知道每一行存放多少个元素;
6.当数组被声明为静态存储类型或外部存储类型时,若不赋初值,数组元素将自动初始化为0;
7.一维数组在内存中占用的字节数为:数组长度*sizeof(基类型);
二维数组占用的字节数为:第一维长度*第二维长度*sizeof(基类型);
//例8-1 从键盘输入某年某月(包括闰年),编程输出该年的该月拥有的天数
#include<stdio.h>
#define MONTHS 12
int main()
{
int days[2][MONTHS]={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}};
int year,month;
do{
printf("Enter year ,month:");
scanf("%d %d",&year,&month);
}while(month<1||month>12);
if(((year%4==0)&&(year%100!=0))||(year%400==0))
{
printf("The number of days is %d\n",days[1][month-1]);
}
else{
printf("The number of days is %d\n",days[0][month-1]);
}
return 0;
}
8.向函数传递一维数组:
①把一个数组传递给一个函数,将这个数组的数组名作为函数实参调用函数即可;
②数组作函数形参时,数组的大小不用出现在方括号内,最好用一个单独的形参传递数组的大小;
③如果方括号内出现了数字,若是正数,则忽略,若是负数,则编译出错;
④方括号内的数字不能真正表示接收的数组大小;
/*例8-2 从键盘输入某班学生某门课的成绩(每班人数最多不超过40人),当输入成绩为
负值时,表示输入结束,试编程计算并输出其平均分,并输出实际输入的学生人数。
#include"stdio.h"
int Input(float a[]);
float Aver(float a[],int n);
float Max(float a[],int n);
#define N 40
int main()
{
int n;
float score[N];
float aver,MaxScore;
n=Input(score);
aver=Aver(score,n);
Max=
printf("学生人数:%d\n",n);
printf("平均成绩:%f\n",aver);
return 0;
}
//输入-1时结束输入
int Input(float a[])
{
int i=-1;
do{
i++;
printf("Please enter score:");
scanf("%f",&a[i]);
}while(a[i]>=0);
return i;
}
float Aver(float a[],int n)
{
float sum=0;
int i;
for(i=0;i<n;i++)
{
sum+=a[i];
}
return (n>0?(sum/n):-1);
}
float Max(float a[],int n)
{
int i;
float maxScore=a[0];
for(i=0;i<n;i++)
{
if(maxScore<a[i])
{
maxScore=a[i];
}
}
return maxScore;
}
9.排序
(1)交换法排序(降序)
void DataSort(int score[],int n)
{
int i,j,temp;
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
if(score[i]<score[j])
{
temp=score[i];
score[i]=score[j];
score[j]=temp;
}
}
}
}
(2)选择法排序(降序)
void DataSort(int score[],long num[],int n)
{
int i,j,k;
int temp,temp2;
for(i=0;i<n-1;i++)
{
k=i;
for(j=i+1;j<n;j++)
{
if(score[k]<score[j])
{
k=j;
}
}
if(k!=i)
{
temp=score[k];score[k]=score[i];score[i]=temp;
temp2=num[k];num[k]=num[i];num[i]=temp2;
}
}
}
(3)冒泡法排序(沉降法,升序)
原理:
①i只表示轮,j表示数组的下标
②共n-1轮:每轮将该轮参与比较最大的数沉下去,沉下n-1个数,就完成了排序
③每轮比较n-i次,将原定顺序的数依次和下面的数比较,大的沉下去
分析:
n个数需要n-1次比较才能将最大数找出来;
第i轮已经沉下去i-1个数;
还有n-i+1个数参与比较;
故找出最大数每轮需要比较(n-i+1)-1=n-i次;
void DataSort(int a[],int n)
{
int i,j,temp;
for(i=1;i<n;i++)
{
for(j=0;j<n-i;j++)
{
if(a[j]>a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}
10.查找
//折半查找法,找到返回x在数组中的下标,否则返回-1
//前提要求:num[]中的数据必须是从小到大排好序的
int Search(long num[],int n,long x)
{
int left=0,right=n-1,mid;
int pos=-1;
int flag=0;
while((!flag)&&(left<=right))
{
mid=(left+right)/2.0;
if(x>num[mid])
{
left=mid;
}
else if(x<num[mid])
{
right=mid;
}
else
{
pos=mid;
flag=1;
}
}
return pos;
}
11.向函数传递二维数组
//例8-3 某班期末考试科目为数学(MT),英语(EN)和物理(PH),有最多不超多40人
参加考试。编程计算:(1)每个学生的总分和平均分;(2)每门课程的总分和平均分
#include"stdio.h"
#define COURSE_N 3
#define N 40
int ReadScore(int score[][COURSE_N],long num[]);
void AverforStu(int score[][COURSE_N],int sum[],float aver[],int n);
void AverforCour(int score[][COURSE_N],int sum[],float aver[],int n);
void Print(int score[][COURSE_N],long num[],int sumS[],float averS[],int sumC[],float averC[],int n);
int main()
{
int score[N][COURSE_N],sumS[N],sumC[COURSE_N],n;
long num[N];
float averS[N],averC[COURSE_N];
n=ReadScore(score,num);
AverforStu(score,sumS,averS,n);//计算每个学生的总分和平均分
AverforCour(score,sumC,averC,n);//计算每门课的总分和平均分
Print(score,num,sumS,averS,sumC,averC,n);//输出学生成绩
return 0;
}
//函数功能:输入学生的学号及三门课的成绩,返回学生人数
int ReadScore(int score[][COURSE_N],long num[])
{
int i,j,n;
printf("请输入学生人数:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("请输入第%d个学生的学号:",i+1);
scanf("%ld",&num[i]);
for(j=0;j<COURSE_N;j++)
{
printf("请输入第%d门课成绩:",j+1);
scanf("%d",&score[i][j]);
}
}
return n;
}
//函数功能:计算每个学生的总分和平均分
void AverforStu(int score[][COURSE_N],int sum[],float aver[],int n)
{
int i,j;
for(i=0;i<n;i++)
{
sum[i]=0;
for(j=0;j<COURSE_N;j++)
{
sum[i]+=score[i][j];
}
aver[i]=(float)sum[i]/COURSE_N;
}
}
//函数功能:计算每门课程的总分和平均分
void AverforCour(int score[][COURSE_N],int sum[],float aver[],int n)
{
int i,j;
for(j=0;j<COURSE_N;j++)
{
sum[j]=0;
for(i=0;i<n;i++)
{
sum[j]+=score[i][j];
}
aver[j]=(float)sum[j]/n;
}
}
//函数功能:显示每个学生的学号,各门课成绩,总分,平均分,及每门课的总分和平均分
void Print(int score[][COURSE_N],long num[],int sumS[],float averS[],int sumC[],float averC[],int n)
{
int i,j;
printf("学号\t\t数学成绩 英语成绩 物理成绩 总分 平均分\n");
for(i=0;i<n;i++)
{
printf("%-12ld\t",num[i]);
for(j=0;j<COURSE_N;j++)
{
printf("%-9d ",score[i][j]);
}
printf("%4d\t %5.1f\n",sumS[i],averS[i]);
}
printf("\n");
printf("每门课的成绩:\t");
for(j=0;j<COURSE_N;j++)
{
printf("%4d\t",sumC[j]);
}
printf("每门课的平均分:\t");
for(j=0;j<COURSE_N;j++)
{
printf("%4.1f\t",averC[j]);
}
printf("\n");
}