在 C 中传递一个指针数组是什么意思?

What does it mean to pass an array of pointers in 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 的别名,但根据语法 a 应该是一个数组,即。 print() 函数的激活记录应该包含一个数组,而不仅仅是一个包含 x 基地址的指针变量,但这是一个指针或指针数组的全部混淆,语法肯定表明它应该是一个 int 指针数组,我在网上阅读但更加困惑,请不要通过标记无关来忽略这个问题。

在两种情况下,数组“衰减”为指向其第一项的指针:

  • 只要在(大多数)表达式中使用数组名称,或
  • 当函数参数声明为数组类型时。

int *x[] = {a1,a2,a3}; 起作用的原因是因为这 3 个数组“衰减”为指向其第一个元素的指针。在所有 3 种情况下都是 int* 类型,因此它与 x 数组的元素类型兼容。

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

这也是多级间接 a[0][2] 起作用的原因。这是 而不是 因为 a 是二维数组 - 它不是。但是第一个 []int** 类型进行指针运算以获得相关的 int* 元素。第二个依次对该指针元素进行指针运算,以获得实际的 int.

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

a[-1][1] 是一个错误,因为它调用了未定义的行为 - 我们不应该编写那样的程序,原因是它本身有点高级的主题。详细信息在这里:Is it undefined behaviour to just make a pointer point outside boundaries of an array without dereferencing it?