数组名的蜕化
数组在作为函数参数时,数组名将蜕化为指针。书上为什么这么说呢?书上的意思是说这家伙已经蜕化得不知道自己有几个元素了。举个例子:
void fun(char array[5]);
在编译时编译器会当成是:void fun(char *array);你在这个函数中使用sizeof(a)得到的值是4,而在定义char array[5]的函数中sizeof(array) = 5,说明确实已经蜕化为指针了。所以你写:
char *pa = array ; //正确,指针到指针
数组名退化为指针,在这里强调一下:数组的元素类型仍然存在!这里要注意的是多维数组的情况。
以2维数组为例:
void fun2(char arrayMulti[3][5]);
那么在函数fun2中,arrayMulti蜕化成的是char (*)[5],即:指向char[5]类型的指针,因为前面分析过arrayMulti的元素的类型是char[5],所以在程序中:
char **pm = arrayMulti ; //错误:从char (*)[5]到 char **的赋值
char (*pm5)[5] ;
pm5 = arrayMulti ; //正确。
>> 数组在作为函数参数时,数组名将蜕化为指针。书上为什么这么说呢?书上的意思是说这家伙已经蜕化得不知道自己有几个元素了。
很形象,也抓住了重点。
其实根据标准的规定,不仅仅是数组在作为函数参数时数组名将退化为指针——除了作为sizeof和&的操作数之外,在表达式中出现的数组名都不知道自己有几个元素,所以这时它的类型已经不再是数组类型了,而是decay为一个指针。
举例说明:
int a[10]; // 定义 a 的类型为 int[10],数组类型
int* p = a; // a 的类型为 int*,指针类型,不再是数组类型。
a[0] = 0; // a 的类型为 int*,指针类型,不再是数组类型。并且 a[0] = *(a+0) = *a。
sizeof( a ); // a 的类型为 int[10],数组类型。
p = &a; // a 的类型为 int[10],数组类型。因此,&a 的类型为int (*)[10],是指针类型,但是跟 p 的指针类型(int*)不匹配,因此赋值非法。
总之,只要排除了sizeof和&这两种情况,在程序中把数组名作为指针来使用就是了,而且是一个指向数组首元素的指针(即数组名代表的值就是数组第一个元素的地址)。