说我有以下代码。
// x = whatever number
int *arr_of_ptr[x];
int (*ptr_to_arr)[x]
int **p1 = arr_of_ptr;
int **p2 = ptr_to_arr;
我的理解是 arr_of_ptr
是 "dereferencing arr_of_ptr元素的结果是一个int"--因此,arr_of_ptr的元素 arr_of_ptr
是 整数指针. 另一方面,取消引用 ptr_to_arr
结果是一个数组,然后我可以从这个数组中获取整数,因此 ptr_to_arr
指向一个数组.
我也有一个粗浅的理解,数组本身就是指针,而 arr[p]
评价为 (arr + p * sizeof(data_type_of_arr))
其中名 arr
的第一个元素的指针。arr
.
所以,这一切都很好,但有什么办法让我知道,是否有 p1
和 p2
是 pointers to arrays
或 arrays of pointers
在没有预先信息的情况下?
我的困惑主要来自于这样一个事实:(我认为)我们可以评估出 int **p
两种方式。
*(p + n * size)
是什么给我一个int(*p + n * size)
是什么给我一个int现在回想起来,这个问题可能用词不当,因为回想起来我自己都有点糊涂了,但我真的不知道如何更好的表达自己。对不起,我的问题是
最主要的区别是,这个是合法的。
int **p1 = arr_of_ptr;
而这是不合法的
int **p2 = ptr_to_arr;
因为... arr_of_ptr
是一个数组,它可以(在大多数情况下) 衰败 到指向其第一个元素的指针。 因此,由于 arr_of_ptr
属于 int *
元素的指针类型为 int **
所以你可以把它分配给 p1
.
ptr_to_arr
然而,它不是一个数组,而是一个指针,所以没有发生衰减。 你试图将一个类型为 int (*)[x]
类型的表达式。int **
. 这些类型是不兼容的,如果你试图使用 p2
你不会得到你所期望的。
#include <stdio.h>
int main(void) {
// your code goes here
int arr[] = {1,2,3};
int *p1 = &arr[0];
int *p2 = &arr[1];
int *p3 = &arr[2];
int* arr2[3];
arr2[0] = p1;
arr2[1] = p2;
arr2[2] = p3;
int *p4 = &arr;
printf("%d\n", sizeof(p4));
printf("%d\n", sizeof(arr2));
printf("%d\n", *p4); // not **p4
printf("%d\n", **arr2);
return 0;
}
在上面的代码中 胳肢窝 是一个有3个元素的普通整型数组。 p1, p2和 p3 是这些元素的正常指针。 arr2 是一个 指数组 储存 p1, p2和 p3. p4 是一个 数组指针 指向数组 胳肢窝 根据你的问题,你需要区分以下几点 p4 和 arr2 自: p4 是一个指针,它的大小是固定的(8个字节),而 arr2 vaires取决于它包含多少元素(8x3=24)。另外,打印包含在p4中的值时,使用单解引用(*p4)而不是**p4(非法),而打印包含在arr2中的值时,使用双解引用(**arr2)。上述代码的输出是.NET Framework 2.0。
8
24
1
1
首先,是
我还有一个粗浅的理解,就是数组本身是指针,arr[p]的值是(arr + p * sizeof(data_type_of_arr)),其中arr这个名字会衰减为arr的第一个元素的指针。
这并不是严格正确的。 数组不是指针。在大多数情况下。表情 的数组类型将被转换("衰减")为指针类型的表达式,表达式的值将是数组中第一个元素的地址。 这个指针值是根据需要计算出来的,并不存储在任何地方。
当数组表达式的操作数为 sizeof
, _Alignof
或单利 &
操作符,或者说是声明中用来初始化字符数组的字符串文字。
说了这么多。ptr_to_arr
有 指针 类型,而不是数组类型--它不会 "衰减 "到 int **
.
鉴于声明
T arr[N];
以下为真。
Expression Type Decays to Equivalent expression
---------- ---- --------- ---------------------
arr T [N] T * &arr[0]
*arr T n/a arr[0]
arr[i] T n/a n/a
&arr T (*)[N] n/a n/a
表达式 arr
, &arr[0]
和 &arr
都会产生相同的值(与类型之间的表示方式有任何差异)。 arr
和 &arr[0]
具有相同的类型,"指针到 T
" (T *
),而 &arr
类型为 "指向N元素数组的指针"。T
" (T (*)[N]
).
如果你更换 T
带指针类型 P *
因此,该声明现在是
P *arr[N];
你会得到以下内容。
Expression Type Decays to Equivalent expression
---------- ---- --------- ---------------------
arr P *[N] P ** &arr[0]
*arr P * n/a arr[0]
arr[i] P * n/a n/a
&arr P *(*)[N] n/a n/a
所以根据你的声明,更正确的写法是这样的。
int arr[x];
int *p1 = arr; // the expression arr "decays" to int *
int *arr_of_ptr[x];
int **p2 = arr_of_ptr; // the expression arr_of_ptr "decays" to int **
/**
* In the following declarations, the array expressions are operands
* of the unary & operator, so the decay rule doesn't apply.
*/
int (*ptr_to_arr)[x] = &arr;
int *(*ptr_to_arr_of_ptr)[x] = &arr_of_ptr;
再来一次: ptr_to_arr
和 ptr_to_arr_of_ptr
是 指针,而不是数组,也不会衰减到不同的指针类型。