例1:编写程序,输入一个班级的数学成绩,计算平均成绩和通过率
#include
#define N 10//宏定义N是10,代表班级10个同学
int main(void)
{
int score[N];//定义大小为N的数组
double sum=0;//定义总分
int count=0;//定义及格人数
int i;//定义循环变量
for(i=0;i<N;i++)//循环输入N个成绩
{
printf("请输入成绩:",i+1);
scanf("%d",&score[i]);
}
for(i=0;i<N;i++)
{
sum+=score[i];//计算总分
if(score[i]>=60) count++;//统计及格人数
}
printf("平均分:%.1lf\n",sum/N);
printf("通过率:%.1lf%%\n",(double)count*100/N);
return 0;
}
一组相同类型的数据的集合,可以大大减少程序中简单变量的数量,数组中的元素具有相同的名字和数据类型,通过下标来区分,注意数组的下标从0开始
int a[10];//定义一个大小为10的整型数组a
a[5]=100;//对a[5]进行赋值
double degree[24];//定义24小时温度的数据语句
int score[30][4];//30个同学,每个同学4门课,需要定义二维数组
int score[10][30][4];//10个班,30个人,4门课,可以定义三维数组
①一维数组用来储存线性数据,某个值随时间的变化
②二维数组多用来存储平面信息,表格、矩阵运算
③三维数组可以储存空间信息或更复杂的时空信息
数组是一组相同类型的数据的集合,数组中的元素通过下标来区分,数组下标指定数组元素在数组中的位置,由此可以实现数组的随机存取。数组元素的赋值和访问与普通变量一样。
例2:数组的随机存取
int main(void)
{
double a[3];
a[2]=12.3;
a[0]=7.6;
a[1]=8.2;
return 0;
}
同局部变量一样,数组没有初始化之前,值是不确定的
一维数组声明格式:数据类型 数组名[常量表达式];
数组引用方式:数组名[下标表达式];
例3:数组的初始化
#include
int main(void)
{
int a[5];
int index;
for(index=0;index<5;index++)
{
printf("%d\n",a[index]);//循环输出5个数组元素,输出结果是不确定的
}
return 0;
}
//1 定义数组的同时对数组元素赋初值
int a[5]={10,20,30,40,50};
//2 部分元素赋值,其他默认为0
int a[5]={10,20};
//3 如果不指定数组长度,系统会根据初始化值个数自动确定数组大小
int a[]={10,20,30,40,50};
//4 当数组声明为静态数组或全局数组时,系统会对所有数组元素自动初始化为0
static int a[5];
例4:编写程序打印每月天数
#include
#define MONTHS 12
int main(void)
{
int days[MONTHS]={31,28,31,30,31,30,31,31,30,31,30,31};
int index;//用于循环
for(index=0;index<MONTHS;index++)
{
printf("%d月有%d天\n",index+1,days[index]);
}
return 0;
}
注意下标越界问题:C语言并不会对下标越界进行检查,有可能会引发程序崩溃
对数组的使用是通过引用元素实现的,不能将数组作为一个整体使用,输出a,只是输出了a[0]
例5:用循环实现数组输入输出
#include
#define N 5
int main(void)
{
int a[N];
int i;
for(i=0;i<N;i++)//循环输入数据
{
scanf("%d",&a[i]);
}
for(i=0;i<N;i++)
{
printf("%6d",a[i]);//表示输出的宽度是6
}
printf("\n");
return 0;
}
例6:输出斐波那契数列前20,每行输出5个
#include
int main(void)
{
int i;//用于循环
int f[20]={1,1};//默认后面18个是0
for(i=2;i<20;i++)//进行数组赋值
{
f[i]=f[i-1]+f[i-2];
}
for(i=0;i<20;i++)
{
printf("%6d",f[i]);
if((i+1)%5==0)
{
printf("\n");
}
}
return 0;
}
例7:找出数组中的最大值,并于最后一个数字对换
#include
#include
int main(void)
{
int a[10];
int max,maxpos;//定义最大值和最大值下标
int i,temp;//定义循环值和第三个水杯
printf("随机生成原始数组:");
printf("\n");
for(i=0;i<10;i++)
{
a[i]=rand()%90+10;
printf("%4d",a[i]);
}
printf("\n");
max=a[0];maxpos=0;//一一比较
for(i=0;i<10;i++)
{
if(a[i]>max)
{
max=a[i];
maxpos=i;
}
}
printf("max=%d,index=%d",max,maxpos);
printf("\n");
temp=a[9];//水杯接收最后一个
a[9]=max;
a[maxpos]=temp;
for(i=0;i<10;i++)
{
printf("%4d",a[i]);
}
return 0;
}
例8:定义一个大小为10的整型数组,数组元素为互不相同的两位随机正整数
#include
#include
#include
int main(void)
{
int a[10];
int x,i,j;
srand(time(NULL));
i=0;
while(i<10)
{
x=rand()%90+10;
for(j=0;j<i;j++)
{
if(a[j]==x)
{
break;
}
}
if(j==i)
{
a[i]=x;
i++;
}
}
for(i=0;i<10;i++)
{
printf("%4d",a[i]);
}
printf("\n");
return 0;
}
定义格式:数据类型 数组名[第一维大小] [第二维大小]
占用内存字节数:第一维大小 * 第二维大小 * sizeof(数据类型)
//1 定义的时候赋值,没有的默认为0
int a[3][4]={{1,2},{3,4,5}};
//2 默认定义第一维长度
int a[][4]={{1,2},{3,4,5}};//自动补充为2
int a[][3]={1,2,3,4,5,6,7};//自动补充为3
//3 使用双重循环进行人工输入
int a[3][4]
for(i=0;i<3;i++)//第一维长度
{
for(j=0;j<4;j++)//第二维长度
{
scanf("%d",&a[i][j]);
}
}
例9:统计考试成绩,求出同学总分
学号 | 数学 | 语文 | 英语 | 物理 |
---|---|---|---|---|
1 | 90 | 10 | 20 | 30 |
2 | 91 | 20 | 30 | 40 |
3 | 92 | 30 | 40 | 50 |
#include
int main(void)
{
int score[3][4]={{90,10,20,30},
{91,20,30,40},
{92,30,40,50}};
int stu[3]={0,0,0};//存储总成绩
int i,j;
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
stu[i]=stu[i]+score[i][j];
}
}
for(i=0;i<3;i++)
{
printf("%dtotal score:%d\n",i+1,stu[i]);
}
return 0;
}
例10:矩阵转换,其实就是行列互换
#include
int main(void)
{
int a[2][3]={{1,2,3},{4,5,6}};//2行3列的矩阵
int b[3][2];//定义转置之后的矩阵
printf("原矩阵:\n");
int i,j;
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("%d",a[i][j]);
}
printf("\n");
}
for(i=0;i<3;i++)
{
for(j=0;j<2;j++)
{
b[i][j]=a[j][i];
}
}
printf("转置之后的矩阵:\n");
for(i=0;i<3;i++)
{
for(j=0;j<2;j++)
{
printf("%d",b[i][j]);
}
printf("\n");
}
}
函数名代表数组的首地址,数组名可以做实参和形参,传递的是数组的起始地址
例11:编写函数,实现一维数组的输入输出
#include
void input(int a[],int n);//函数原型说明
void print(int a[],int n);//注意,这里是形式参数
int main()
{
int a[10];
input(a,sizeof(a)/sizeof(int));
print(a,sizeof(a)/sizeof(int));
return 0;
}
void input(int a[],int n)
{
int i;//循环计数
printf("请输入%d个数字:\n",n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
}
void print(int a[],int n)
{
int i;
for(i=0;i<n;i++)
{
printf("%5d",a[i]);
}
printf("\n");
}
例12:定义函数求一维数组的平均数
#include
double avg(int a[],int n);
int main(void)
{
int a[3]={11,12,13};
printf("average:%.2f",avg(a,3));
}
double avg(int a[],int n)
{
double sum=0;
int i;
for(i=0;i<n;i++)
{
sum=sum+a[i];
}
return sum/n;
}
(1)如果函数的形参是数组,那么实参必须是数组名,且实参数组与形参数组类型要一致
(2)数组名代表数组首元素的地址,用数组名做函数实参时,只是将实参数组首元素的地址传递给形参,共同占用同一段内存单元,实际上就是同一个数组
//推荐使用后两种
double avg(int a[10],int n);//指定元素个数与实参数组相同
double avg(int a[],int n);//不指定元素的个数
double avg(int [],int);//函数原型说明中可省略参数名
参数的传递方式与一维数组类似,但在对形参数组声明时,必须指定第二维大小,且应与实参的第二维大小相同,这是由数组在内存中的存放特点所决定的,直到一行有几个元素,就可以计算出一共有多少行
形参数组的结构应与实参数组相同,但在第二维大小相同的前提下,形参数组的第一维可以与实参数组不同
int a[3][10];
int a[][10];//这两种都可以
int score[5][10];//实参数组
int a[3][10];
int a[][10];//这两种形参都可以,系统之间差第二维长度,不检查第一维大小
例13:定义函数,输出二维数组
#include
void print(int a[][4],int rows,int cols);
int main()
{
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
print(a,3,4);
return 0;
}
void print(int a[][4],int rows,int cols)
{
int i,j;
for(i=0;i<rows;i++)
{
for(j=0;j<cols;j++)
{
printf("%4d",a[i][j]);
}
printf("\n");
}
}