编译器会把数组名转换为一个指针常量,是数组中的第一个元素的地址,类型就是数组元素的地址类型,如:
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
数组名a若出现在表达式中,如int *p=a;那么它就转换为第一个元素的地址,等价于int *p=&a[0];
只有两种情况下例外:
第一种是对数组名使用sizeof运算符
sizeof(a) :这将会得到整个数组所占的内存大小,a是长度为10个int(4字节)数组,运算结果是40。此时a代表的是数组所占用的那一整块内存。
第二种是对数组名取地址
&a:运算结果是数组的地址。
a 和 &a
虽然a 和 &a 的值是相同的。
但是&a 中的a代表整个数组,而不是指向数组首元素的指针常量。
“取一个数组名的地址所产生的是一个指向数组的指针,而不是一个指向某个指针常量值的指针。
所以 a+1 和 &a +1 不是同一个意义。 a+1 表示下一个元素,&a +1 表示下一个数组。
数组作为函数参数
数组传参时,会退化为指针。 类型是第一个元素的地址类型。
(1)退化的意义:C语言只会以值拷贝的方式传递参数,参数传递时,如果只拷贝整个数组,效率会大大降低,并且在参数位于栈上,太大的数组拷贝将会导致栈溢出。
(2)因此,C语言将数组的传参进行了退化。将整个数组拷贝一份传入函数时,将数组名看做常量指针,传数组首元素的地址。
数组不能自增、自减运算。而指针可以。
二维数组和函数
二维数组作为函数的参数,
如int a[3][4] = {(1,1,1,1),(2,2,2,2),(3,3,3,3),};
sum(a,3);
关键是sum申明的原型
sum(int (ar*)[4],int size); // int (ar*)[4]表示的是数组指针
或者是 sum(int ar[][4],int size);
数组初始化规则
1.只有定义数组时才能使用初始化化,不能将一个数组赋给另一个数组。
只提供一个用逗号分隔的值列表,并将它们用花括号括起来。初始化的值的数量可以少于数组的元素数目,其他的默认设置为0.