在 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?
我正在为 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?