在C中传递指针数组意味着什么



我正在与C的指针概念作斗争,确切地说是与指针数组作斗争。请参阅以下程序以供参考。

#include <stdio.h> 
int a1[] = {6,7,8,18,34,67};
int a2[] = {23,56,28,29};
int a3[] = {-12,27,-31};
int *x[] = {a1,a2,a3};
void print (int *a[]){
printf ("%d",a[0][2]);
printf ("%d",*a[2]);
printf ("%d",*++a[0]);
printf ("%d",*(++a)[0]);
printf ("%d",a[-1][1]);

}
void main (){ 
print (x);
}

我不明白的是,如果我们将int *a[]作为指针数组传递,那么它毕竟应该是一个数组,对吗?但有人告诉我,这里a只是一个单指针变量,它充当x的别名,也就是说,print()函数的激活记录应该包含一个数组,而不仅仅是一个保存x基地址的指针变量,而是整个混乱——它是一个指针还是一个指针数组,语法肯定表明它应该是一个int指针数组,我在网上读过,但更困惑了,请不要忽视这个问题,把它标记为无关紧要。

在两种情况下;衰变";转换为指向其第一项的指针:

  • 每当数组名称用于(大多数(表达式时,或者
  • 使用数组类型声明函数参数时

CCD_ 4工作的原因是因为这3个阵列";衰变;转换为指向其第一个元素的指针。在所有3种情况下都是int*类型,因此它与x阵列的元素类型兼容。

然后,当您定义诸如void print (int *a[])之类的函数时,编译器会静默地隐式地";衰变";将此数组声明转换为指向第一个元素的指针。int* []数组的第一个元素是int*,指向一个元素的指针是int**。所以这个函数等价于void print (int** a);。这就是为什么我们可以在这里写一个空的[]——编译器不关心数组大小,因为它无论如何都会用指针替换数组。

这也是为什么多层间接a[0][2]起作用的原因。这是而不是,因为a是一个2D阵列——它不是。但是第一个[]int**类型进行指针运算以获得相关的int*元素。第二个依次对指针元素进行指针运算,以获得实际的int

至于该函数中的各种行,这是一种人工学校的例子,旨在教授运算符优先级。提示:后缀运算符通常具有最高优先级。

a[-1][1]行是一个错误,因为它调用了未定义的行为——我们不应该写这样的程序,原因是它本身有点高级。这里的详细信息:只让指针指向数组边界之外而不取消引用它,这是未定义的行为吗?

最新更新