首先看一段代码:
void test(int *p)
{
}
int main()
{
int arr[]= {
30, 450,14,5};
test(arr);
return 0;
}
毫无疑问,上面这段代码是运行OK的。因为C语言标准中有以下规则:在函数参数的声明中,数组名被编译器当作指向该数组第一个元素的指针。
第一种错误
那下面这段代码,会正确运行吗
#include <stdlib.h>
void test(int **p)
{
}
int main()
{
int arr[]={
30,450,14,5};
test(&arr);
return 0;
}
可能有的同学认为这段代码是正确的,因为数组作为函数参数时退化成一个指针,那么我对数组进行取址,这样&arr就是一个二维指针了,所以可以作为函数test的入参。
这个理由貌似有道理,但很遗憾,这段代码会报编译错误:
main.c:3:17: note: expected 'int **' but argument is of type 'int (*)[4]'
void test(int **p)
~~~~~~^
这个错误是说,test函数期望的入参类型是int **。但是实际传入的参数类型是 int (*)[4],即实际传入的类型是指向数组的指针。
C语言标准中是定义了:在函数参数的声明中,数组名被编译器当作指向该数组第一个元素的指针。但是你不能因为数组在函数参数中当成一个指针,你对数组名取地址&arr就认为它的类型就是指向指针的指针(int **),这样以为是错的,因为不具备这样的传递性。C语言规范中只规定了数组名作为函数的入参时会被当做一个指针,但是并没有规定对数组取地址会被当成指向指针的指针。
根据上面代码的报错信息提示,将不能编译通过的代码片段作一个小的修改,就会编译通过了:
#include <stdlib.h>