数组是一组相同类型的值,按照顺序储存在一起。数组通过变量名后加方括号表示,方括号里面是数组的成员数量。
int foo[100];
数组初始化和赋值
int foo[100];
foo[0] = 0;
foo[100] = 1; // 不会报错
注意:
1.声明数组时必须给出数组的大小,如int foo[]; 编译过不了。
2.如果引用不存在的数组成员,程序不会抛出数组越界异常。 但是紧跟在foo后面的那个内存区域被赋值,而那实际上是其他变量的区域,因此不知不觉就更改了其他变量的值。这很容易引发错误,而且难以发现。
数组也可以在声明时,使用大括号,同时对每一个成员赋值。
int a[5] = {22, 37, 3490, 18, 95};
注意,使用大括号赋值时,必须在数组声明时赋值,否则编译时会报错。
int a[5];
a = {22, 37, 3490, 18, 95}; // 报错
如果要将整个数组的每一个成员都设置为零,最简单的写法就是下面这样。
int a[100] = {0};
C 语言允许省略方括号里面的数组成员数量,这时将根据大括号里面的值的数量,自动确定数组的长度。
int a[] = {22, 37, 3490};
// 等同于
int a[3] = {22, 37, 3490};
上面示例中,数组a
的长度,将根据大括号里面的值的数量,确定为3
。
省略成员数量时,如果同时采用指定位置的赋值,那么数组长度将是最大的指定位置再加1。
int a[] = {[2] = 6, [9] = 12};
上面示例中,数组a
的最大指定位置是9
,所以数组的长度是10。
数组的地址
数组是一连串连续储存的同类型值,只要获得起始地址(首个成员的内存地址),就能推算出其他成员的地址。请看下面的例子。
int a[5] = {11, 22, 33, 44, 55};
int* p;
p = &a[0];
printf("%d\n", *p); // Prints "11"
注意,数组名指向的地址是不能更改的。声明数组时,编译器自动为数组分配了内存地址,这个地址与数组名是绑定的,不可更改,下面的代码会报错。
int ints[100];
ints = NULL; // 报错
数组指针的加减法
C 语言里面,数组名可以进行加法和减法运算,等同于在数组成员之间前后移动,即从一个成员的内存地址移动到另一个成员的内存地址。比如,a + 1
返回下一个成员的地址,a - 1
返回上一个成员的地址。
int a[] = {11, 22, 33, 44, 55, 999};
int* p = a;
while (*p != 999) {
printf("%d\n", *p);
p++;
}
上面示例中,通过p++
让变量p
指向下一个成员。
注意,数组名指向的地址是不能变的,所以上例中,不能直接对a
进行自增,即a++
的写法是错的,必须将a
的地址赋值给指针变量p
,然后对p
进行自增。