定义及使用:
想要定义一连串相同类型的数据,那么就可以用数组来进行定义。
如 int arr[10] = {0}
这段定义是创建一个名字为arr的整形数组,其内存储10个整形,将这十个数都初始化为0。当我们需要访问这10个元素时,我们采用下标的方式进行访问。由于数组是连续定义的,所以规定,数组中第一个元素下标为0,第二个为1,第三个为2...当我们想访问第5个元素,那么我们用arr[4]来表示。由于数组的连续性,我们通常搭配for循环来对数组进行初始化及访问等操作。
需要注意的是:
数组创建,在C99标准之前, [] 中要给一个常量才可以,不能使用变量。在C99标准支持了变长数 组的概念。
数组的存储方式:
#include <stdio.h>
int main() {
int arr[10] = {0};
int i = 0;
int sz = sizeof(arr)/sizeof(arr[0]);
for(i=0; i<sz; ++i)
{
printf("&arr[%d] = %p\n", i, &arr[i]);
}
return 0; }
通过打印这段代码,我们可以清晰的看到数组各个元素所存储的位置,他们是连续排列的,中间相差的元素大小正好是我们所定义的类型的大小。比如说int类型,两个元素中间就相差了4个元素。
二维数组的创建与初始化:
我们通常以下面这种写法来创建二维数组:int arr[2][2] = {{2,3},{4,5}};
这段代码的意思是,我们创建的这个二维数组是两行两列的,2为第一行第一列,3为第一行第二列。在使用时,也和一维数组是一样的,用下标进行访问,二维数组的下标依然是从0开始,比如第一行第一个元素就是arr[0][0]
需要注意的是:
我们也可以创建的数组的行与列大于初始化的数组,比如int arr[2][4] = {{2,3},{4,5}};
并且,我们还可以省略行,只定义列,这需要我们有初始化,int arr[][4] = {{2,3},{4,5}};
但是,我们不能省略列,因为当我们省略行时,电脑会根据我们的初始化自动安排合理的行数,但如果没初始化列,列的个数可以随便定义,因此不能省略列。
二维数组的存储方式:
#include <stdio.h>
int main() {
int arr[3][4];
int i = 0;
for(i=0; i<3; i++)
{
int j = 0;
for(j=0; j<4; j++)
{
printf("&arr[%d][%d] = %p\n", i, j,&arr[i][j]);
}
}
return 0; }
通过这段代码,我们可以观察到二维数组的存储方式和一维数组都是连续的。和我们想象的矩阵的形状不同,二维数组是线形存储的,只是我们对其加以修饰使其按照我们的想象访问各个元素。
数组的越界:
值得注意的是,比如我们初始化arr[10],那么我们数组元素的下标最多到9,当我们执意要访问10及以后的元素时,我们访问的都是随机值,编译器有可能报错也有可能不报错。这就和查酒驾是一样的,警察只在有可能出现酒驾的地方进行设防,而并非每条路都查酒驾,所以当编译器没有报错并不意味着代码没错。
数组名:
需要注意的是,数组名有时代表着整个数组,有时代表数组的第一个元素。当数组传参时传过去的只是数组的首元素,因此无法在函数内计算数组的大小。
有两种情况下数组代表整个数组,其他情况下,数组名代表数组首元素。
1. sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数 组。
2. &数组名,取出的是数组的地址。&数组名,数组名表示整个数组。