数组是一组相同类型的元素的集合,其中,有两个关键点。
1.数组中存放了一个或者多个数据,数组的元素个数不能为0.
2.一个数组中的所有数据的类型是相同的。
数组分为一维数组和多维数组,多维数组中较为常见的是二维数组。
数组的创建语法如下:
type arr_name[常量值];
type指数组中存储的数据的类型,可以是int、float、char、short等,也可以是自定义的类型。
arr_name指数组的名字,名字可以任取,最好是根据实际情况取有意义的名字。
[ ]中常量值用于控制数组的大小,即储存数据的上限,根据实际需求来规定。
与创建变量时相似,在创建数组的时候,我们需要给定⼀些初始值,这种就称为初始化。
在初始化数组时,我们一般使用大括号,将要存放的数据放在大括号中。
//完全初始化
int arr[4] = { 1 , 2 , 3 , 4 };
//部分初始化
int arr[4] = { 1 };//将第一项初始化为1,其他项默认初始化为0
//省略数组大小
int arr[] { 1 , 2 , 3 , 4 };//初始化后系统将会自动计算数组大小
//错误的初始化
int arr[4] = { 1 , 2 , 3 , 4 , 5};//初始化的项数多余数组大小
数组也拥有类型,其类型就是去掉数组名的部分。
int arr1[10];
char arr2[6];
float arr3[5];
数组arr1的类型为int [10]。
数组arr2的类型为char[6]。
数组arr1的类型为float [5]。
学习了⼀维数组的基本语法,⼀维数组可以存放数据,存放数据的⽬的是对数据的操作,那我们如何 使⽤⼀维数组呢?
C语言规定数组是有下标的,下标是从0开始的,假设数组有n个元素,最后⼀个元素的下标是n-1,下标就相当于数组元素的编号,如下:
int arr[5] = {1,2,3,4,5};
//数组元素 1 2 3 4 5
//元素下标 0 1 2 3 4
在C语⾔中数组的访问提供了⼀个操作符 [ ] ,这个操作符叫:下标引用操作符。
利用下标引用操作符我们可以轻松访问数组中的元素:
#include
int main()
{
int arr[6] = {1,2,3,4,5,6};
printf("%d ",arr[3]);
printf("%d ",arr[5]);
return 0;
}
当我们想要访问整个数组的元素时,只需要产生所有的数组元素下标,进而就能访问所有的数组元素:
#include
int main()
{
int i;
int arr[6] = {1,2,3,4,5,6};
for(i = 0;i < 6;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
我们也可以根据自己的需求自己给数组输入元素:
#include
int main()
{
int i;
int arr[6] = {0};
for(i = 0 ;i < 6 ;i++)
{
scanf("%d",&arr[i]);
}
for(i = 0 ;i < 6 ;i++)
{
printf("%d",arr[i]);
}
return 0;
}
有了前面的知识,我们使用数组基本就没有什么障碍了,但如果我们要深入了解数组,我们最好能了解一下数组在内存中的存储。
打印数组中各个元素的地址:
#include
int main()
{
int i;
int arr[6] = {0};
for(i = 0 ;i < 6 ;i++)
{
printf("&arr[%d] = %p\n",i,&arr[i]);
}
return 0;
}
这是打印结果:
&arr[0] = 000000859C3FFA30
&arr[1] = 000000859C3FFA34
&arr[2] = 000000859C3FFA38
&arr[3] = 000000859C3FFA3C
&arr[4] = 000000859C3FFA40
&arr[5] = 000000859C3FFA44
其中,我们可以发现,数组元素的地址是随着下标变大而增大的,并且相邻的两个元素之间相差4,这是因为一个int类型的数据占据4个字节。所有,我们可以得出结论:数组在内存中是连续存放的。
在实际运用中,我们常常想知道数组的大小,而C语言中一个办法可以直接计算出数组大小。
sizeof 中C语言是⼀个关键字,可以计算类型或者变量大小,其实sizeof也可以用来计算数组的大小。
例如:
#include
int main()
{
int arr[6] = {0};
printf("%d\n",sizeof(arr));
return 0;
}
输出结果为24,单位为字节,sizeof()计算的是数组在内存中所占的空间大小。
我们知道,数组中的元素类型是相同的,所以,只需要知道一个元素所占据的字节大小,再用数组总大小除以这个值,就可以得到元素个数,也就是数组大小。
#include
int main()
{
int arr[6] = {0};
printf("%d\n",sizeof(arr)/sizeof(arr[0]));
return 0;
}
此时,输出为6,表示数组大小为6。
前面学习的数组被称为一维数组,数组的元素都是内置类型的,如果我们把一维数组做为数组的元 素,这时候就是二维数组,二维数组作为数组元素的数组被称为三维数组,二维数组以上的数组统称为多维数组。
二维数组的创建语法如下:
type arr_name[常量值1][常量值2];
//例如:
int arr1[3][4]
int代表了这个二维数组中的元素类型为整型。
arr1为数组名。
3代表了3行;4代表了4列,即每一行有4个元素。
//完全初始化
int arr[3][3] = {1,2,3, 2,3,4, 3,4,5};
1 2 3
2 3 4
3 4 5
//不完全初始化
int arr[3][3] = {1,2};//第一行第一、二个元素分别初始化为1、2,其余均默认初始化为0
1 2 0
0 0 0
0 0 0
//分行初始化
int arr[3][3] = {{1,2},{2,3},{3,4}};
1 2 0
2 3 0
3 4 0
//初始化时可以省略行,但不可以省略列
int arr[][3] = {{1,2},{2,3},{3,4}}
1 2 0
2 3 0
3 4 0
访问二维数组与访问一维数组相似,都是通过下标来访问数组元素,不过二维数组需要两个下标才能锁定唯一的元素。
与一维数组相同,二维数组的下标也是从0开始:
#include
int main()
{
int i,j;
int arr[3][3] = {1,2,3, 2,3,4, 3,4,5};
for(i = 0;i < 3;i++)
{
for(j = 0;j < 3;j++)
{
printf("arr[%d][%d] = %d ",i,j,arr[i][j]);
}
printf("\n");
}
return 0;
}
//输出结果
arr[0][0] = 1 arr[0][1] = 2 arr[0][2] = 3
arr[1][0] = 2 arr[1][1] = 3 arr[1][2] = 4
arr[2][0] = 3 arr[2][1] = 4 arr[2][2] = 5
与一维数组的输入方式相似,区别在于二维数组多了一个需要确定的下标:
#include
int main()
{
int i,j;
int arr[3][3] = {0};
for(i = 0;i < 3;i++)
{
for(j = 0;j < 3;j++)
{
scanf("%d",&arr[i][j]);
}
printf("\n");
}
for(i = 0;i < 3;i++)
{
for(j = 0;j < 3;j++)
{
printf("arr[%d][%d] = %d ",i,j,arr[i][j]);
}
printf("\n");
}
return 0;
}
我们来看看二维数组的储存规则是否与一维数组相同:
打印各个元素的地址:
#include
int main()
{
int i,j;
int arr[3][3] = {0};
for(i = 0;i < 3;i++)
{
for(j = 0;j < 3;j++)
{
printf("&arr[%d][%d] = %p\n",i,j,&arr[i][j]);
}
}
return 0;
}
&arr[0][0] = 000000FBBC9FFDD0
&arr[0][1] = 000000FBBC9FFDD4
&arr[0][2] = 000000FBBC9FFDD8
&arr[1][0] = 000000FBBC9FFDDC
&arr[1][1] = 000000FBBC9FFDE0
&arr[1][2] = 000000FBBC9FFDE4
&arr[2][0] = 000000FBBC9FFDE8
&arr[2][1] = 000000FBBC9FFDEC
&arr[2][2] = 000000FBBC9FFDF0
我们可以发现与一维数组元素的地址相对比,二维数组元素的地址也是随下标增大而增大,相邻元素的地址相差4,与一维数组相同,因此,二维数组的元素也是连续存储的。
在C99标准之前,C语言在创建数组的时候,数组的大小只能使用常量、常量表达式来指定,或者是在初始化数组的时候,省略数组大小。这样的语法限制,让我们创建数组就不够灵活,有时候数组大了浪费空间,数组小了又不够用。
而C99则给出了一个名为变长数组(variable-lengtharray,简称VLA)的新特性,允许我们使用变量指定数组大小。
int n = a+b;
int arr[n];
上面示例中,数组arr就是变⻓数组,因为它的长度取决于变量n的值,编译器没法事先确定,只有运行时才能知道n是多少。
变长数组的根本特征就是数组长度只有运行时才能确定,因此变长数组不能初始化。它的好处是程序员在开发时,不需要随意为数组指定⼀个估计的长度,程序可以在运行时为数组分配精确的长度。有一个比较迷惑的地方是,变长数组的意思是数组的大小是可以使用变量来指定的,在程序运行的时候,根据变量的大小来指定数组的元素个数,而不是说数组的大小是可变的。数组的大小⼀旦确定就不能再变化了。
是否拥有这个功能与编译器有关系,有兴趣可以自己进行尝试。