1.数组:
是一些具有相同类型的数据的集合,数组中的数据按照一定的顺序排列存放
为什么要使用数组?
就是比方说给出一道题,需要多个变量用于某个循环当中,数量小时当然可以一个个定义出来拿去用,但一旦数值大的时候,就是个累活,还占空间,多了很多行代码,因此我们就可以使用数组,来减少代码量让表达更简洁,易读。而这些变量,只需要在同一个数组名下,用下标区分就可以了。
2.一维数组
(1)数组的定义:
类型名 数组名[ 数组长度 ];
数组长度指的是这个数组里有多少个元素,因此必须是一个确定的整形常量表达式。
(2)数组的引用:
数组名[ 下标 ];
下标(索引)的取值范围是[0,数组长度-1] ,可以是变量也可以是常量。
只能引用单个数组元素,不能一次性引用多个或全部元素。
(3)数组名:
是一个地址常量,用来存放数组内存空间的首地址。
是一个合法的标识符,即由数字,字母或者下划线组合,数字不能放在开头。
(4)初始化:
类型名 数组名[ 数组长度 ]={ 初值表 };
静态存储数组中,没有初始化(即赋予一个值)的元素,系统会自动赋值0。 而在动态存储数组中,系统则会自动赋随机值。
若数组初始化时对全部元素都赋了值,可以省略数组长度。
3.二维数组(矩阵)
( 1)定义:
类型名 数组名[ 行长度 ][ 列长度 ] ;
(2)引用 :
数组名[ 行下标 ][ 列下标 ]
下标的合理取值范围均是 [0,长度-1]
在引用的时候,谨记不要越界。即,int a[10][10]; 但是在引用数组的时候,引用了a[11][10],不管是行还是列,下标的取值超出取值范围就叫做越界。一维数组同是如此。
(3)初始化:
第一种方法:分行赋值法
类型名 数组名[ 行长度 ][ 列长度 ] = {{初值表0},{初值表1}....};
每一个初值表,都代表一行的元素数据。
第二种方法:顺序赋值法
类型名 数组名[ 行长度 ][ 列长度 ] = {初值表};
按着初值表的顺序,依照给出的行长度,每当输出的数达到行长度的倍数时就换行
( ps:当全部元素都被赋值的时候,行长度是可以省略的,但是列长度不可以省略)
4.数组的循环
数组的使用离不开循环,将数组的下标作为循环的变量,通过循环,就可以逐个访问数组中的所有元素(也叫做遍历)。
其中,要注意的有:
(1)二维数组的循环:外循环控制行 内循环控制列;
(2)字符数组的循环:利用字符串特有的结束符’\0‘,作为循环的控制条件
5.字符数组:用于存放字符型数据
在c语言中,字符串作为一个特殊的一维字符数组。
(1) 一维字符数组的定义引用初始化与一维数组相同。
char 数组名[数组长度];
e.g char t[5]={'H','a','p','p','y'};
(2)字符常量:一般以‘ ’单引号的形式出现,引号内可以是数/转义字符..
字符串常量:一般以“ ”双引号形式出现,有一个结束标志‘\0’(一对用双引号括起来的 字符 序列,即一串字符)
【在循环中,一般以数组元素是否为结束符’\0‘作为循环控制条件】
(3)字符串的存储
数组初始化:
比如字符串放入字符数组中static char t[6]={'H','a','p','p','y',‘\0’};
比如使用字符串常量static char t[6]={"Happy"};
static char t[6]="Happy";
赋值与输入: 采用赋值的方法,将某字符串存入到数组当中;
比如 static char str[10];
str[0]=’a’;
(4)在printf输出函数中:
字符常量使用%c,字符串常量使用%s
ps: 由chard定义的数组叫做字符数组,判断字符数组是否为字符串,就看末位有无‘\0’
(5)字符串的字节长度判断:需要把隐藏的‘\0’算上。在‘\0’结束前进行判断,前有多少个字符,有效字节长度就为多少
6.典型例题:(选自c语言程序设计何钦铭)
1)一维数组——选择排序
输入n(n<10),再输入n个数,用选择法将它们从小到大排序后输出。
#include<stdio.h>
#define MAXN 10
int main(void){
int i,n,index;
int k;
int a[MAXN];
printf("enter n:");
scanf("%d",&n);
printf("enter %d numbers",n);
for(i=0;i<n;i++){
scanf("%d",&a[i]);}//输入数组中的每一个元素
//该算法这样想:k=0的时候,相当于是数组中的第一个元素,通过index=k,设定第一个元素就是当下最小的,然后在这个基础上进行内部循环,这时使用i作为变量i=k+1
//i亦是数组的下标,此时i不能和k相同,要在k之上,对i进行累加循环,输出a[i],依次判断a[i]是否<a[k];
//若小于那么就交换下标值,与a[k]交换位置;若没有小于的,就结束i这一层的循环,回到k的循环中,进行第一次累加,k=1
for(k=0;k<n-1;k++){//即是k=n-1时,还剩下最后一个数,直接就在这一层循环中结束了代码运行;
index=k;//假设最小值为k
//求最小值对应数组中的元素下标
for(i=k+1;i<n;i++){
if(a[i]<a[index]){
index=i;
}
}//交换变量,将最小值和a[k]交换,此时第一次循环,a[k]相当于是第一个元素
int temp;
temp=a[index];
a[index]=a[k];
a[k]=temp;
}
printf("最后的排序是:");
for(i=0;i<n;i++){
printf("%d",a[i]);
}
printf("\n");
return 0;
}
2)二维数组——矩阵(外行内列)
输入两个正整数m和n(1≤m,n≤6),再输入一个1个m×n的矩阵,找出最大值以及它的行下标和列下标。假设最大值唯一。
row:记录最大值的行下标
col: 记录最大值的列下标
a[row][col] :最大值
#include<stdio.h>
#define MAXN 6
int main (void){
int row,col;//定义行列变量,column(col)列,row行
int i,n,m,j;
int a[MAXN][MAXN];
printf("Enter n,m:");
scanf("%d%d",&n,&m);
printf("please enter %d*%d个数字:",n,m);//提示输入矩阵的行数列数
for(i=0;i<n;i++){//i n对应行,先行后列
for(j=0;j<m;j++){//j m对应列
scanf("%d",&a[i][j]);
//在第一层循环中,将i=0,即第一行,然后进入第二层,j=0,输出a[0][0],即这个是第一个元素在第一行第一列
//紧接着,第二层循环没有结束,继续对j进行累加,每累加一次输出一个元素,这个元素依旧是在第一行的位置上,只是列位不同
//直到j=6时,第一次总循环结束,接着到第二次循环,在i累加1的基础上进行j的循环,直到i=6,j=6时,最后一个元素输出循环结束,
}
}
row=col=0;//依旧如之前一样,row,col.对应的是元素的下标,假设第一个为最大的。
for(i=0;i<n;i++){
for(j=0;j<m;j++){
if(a[i][j]>a[row][col]){
row=i;
col=j;
}
}
}
printf("max=a[%d][%d]=%d",row,col,a[row][col]);
return 0;}