C 指向 array/array 的指针消歧(扩展)
C pointer to array/array of pointers disambiguation (extended)
There is a post where different pointer notations are explained:
int* arr1[8]; // An array of int pointers.
int (*arr2)[8]; // A pointer to an array of integers
int *(arr3[8]); // The same as the first one
但是也可以这样定义:
int (*arr4[8])
这里除了数据类型名称之外的所有内容都用括号括起来。它与前三个选项有何不同?
我也试过像 (int *arr4[8])
那样把它括起来,但似乎这在 C 中是无效的。
我也很好奇这样的构造:
int (*arr5[8])[8]
不确定,但我认为这类似于指向整数数组的指针数组。
如果我需要指定一个指向这种构造的指针,我认为这是这样的:
int (*(*arr5[8]))[8]
如果我把最外面的括号放在一边,我猜这类似于 指向整数指针数组的指针数组,是吗?
int *(*arr5[8])[8]
都对吗?提前致谢!
您可以将声明符括在括号中。
这个声明
int (*arr4[8]);
声明了一个类型为 int *
的包含 8 个元素的数组。和写
一样
int * arr4[8];
至于这个声明
int (*(*arr5[8]))[8];
为了清楚起见,请考虑以下演示程序。
#include <stdio.h>
int main(void)
{
int a1[8] = { [0] = 10 };
int a2[8] = { [0] = 20 };
int ( *p1 )[8] = &a1;
int ( *p2 )[8] = &a2;
int (*(*arr5[8]))[8] =
{
&p1, &p2
};
printf( "%d\n", ( **arr5[0] )[0] );
printf( "%d\n", ( **arr5[1] )[0] );
return 0;
}
程序输出为
10
20
就是这个声明
int (*(*arr5[8]))[8]
声明了一个指针数组,这些指针指向类型为 int[8]
的数组。
int (*arr4[8])
Here everything except the datatype name is enclosed with parentheses. How is it different from the firts three options?
括号唯一重要的时候是当它们改变运算符的默认优先级时。后缀 []
和 ()
在声明符和表达式中都比一元 *
具有更高的优先级,因此 *arr4[8]
被解析为 *(arr4[8])
。 (*arr4[8])
不影响 *
或 []
的优先级,因此它与编写 *(arr4[8])
和 *arr4[8]
相同。但是,对于 (*arr3)[8]
,他们 do 改变了优先级,明确地将 *
运算符与 arr
.
分组
I tried to enclose it like (int *arr4[8])
as well, but seems like this is not valid in C.
这不是 - 语法不允许。
int (*arr5[8])[8]
Not sure, but I presume this is something like an array of pointers to an array of integers.
准确地说,arr5
是指向int
的8元素数组的指针的8元素数组。从图形上看,它看起来像这样:
+---+ +---+---+---+---+---+---+---+---+
arr5: | | arr5[0] ----------> | | | | | | | | |
+---+ +---+---+---+---+---+---+---+---+
| | arr5[1] --------+
+---+ | +---+---+---+---+---+---+---+---+
| | arr5[2] ------+ +-> | | | | | | | | |
+---+ | +---+---+---+---+---+---+---+---+
... |
| +---+---+---+---+---+---+---+---+
+---> | | | | | | | | |
+---+---+---+---+---+---+---+---+
你会将每个元素索引为 (*arr5[i])[j]
- 你不想索引到每个 arr5[i]
,你想索引到每个 arr5[i]
点至。声明者预先告诉你这一点——你不必自己去弄明白。声明符的结构反映了表达式的结构。
请注意,此声明不会创建 int
的 8 元素数组 - 它 仅 创建一个 8 元素指针数组。您可能需要为每个要指向的 arr5[i]
动态分配内存,例如:
for ( size_t i = 0; i < 8; i++ )
arr5[i] = malloc( sizeof *arr5[i] ); // sizeof *arr5[i] == sizeof (int [8])
或者已经声明了一堆数组:
int foo[8];
int bar[8];
int bletch[8];
...
int (*arr5[8])[8] = { &foo, &bar, &bletch, ... };
There is a post where different pointer notations are explained:
int* arr1[8]; // An array of int pointers.
int (*arr2)[8]; // A pointer to an array of integers
int *(arr3[8]); // The same as the first one
但是也可以这样定义:
int (*arr4[8])
这里除了数据类型名称之外的所有内容都用括号括起来。它与前三个选项有何不同?
我也试过像 (int *arr4[8])
那样把它括起来,但似乎这在 C 中是无效的。
我也很好奇这样的构造:
int (*arr5[8])[8]
不确定,但我认为这类似于指向整数数组的指针数组。 如果我需要指定一个指向这种构造的指针,我认为这是这样的:
int (*(*arr5[8]))[8]
如果我把最外面的括号放在一边,我猜这类似于 指向整数指针数组的指针数组,是吗?
int *(*arr5[8])[8]
都对吗?提前致谢!
您可以将声明符括在括号中。
这个声明
int (*arr4[8]);
声明了一个类型为 int *
的包含 8 个元素的数组。和写
int * arr4[8];
至于这个声明
int (*(*arr5[8]))[8];
为了清楚起见,请考虑以下演示程序。
#include <stdio.h>
int main(void)
{
int a1[8] = { [0] = 10 };
int a2[8] = { [0] = 20 };
int ( *p1 )[8] = &a1;
int ( *p2 )[8] = &a2;
int (*(*arr5[8]))[8] =
{
&p1, &p2
};
printf( "%d\n", ( **arr5[0] )[0] );
printf( "%d\n", ( **arr5[1] )[0] );
return 0;
}
程序输出为
10
20
就是这个声明
int (*(*arr5[8]))[8]
声明了一个指针数组,这些指针指向类型为 int[8]
的数组。
int (*arr4[8])
Here everything except the datatype name is enclosed with parentheses. How is it different from the firts three options?
括号唯一重要的时候是当它们改变运算符的默认优先级时。后缀 []
和 ()
在声明符和表达式中都比一元 *
具有更高的优先级,因此 *arr4[8]
被解析为 *(arr4[8])
。 (*arr4[8])
不影响 *
或 []
的优先级,因此它与编写 *(arr4[8])
和 *arr4[8]
相同。但是,对于 (*arr3)[8]
,他们 do 改变了优先级,明确地将 *
运算符与 arr
.
I tried to enclose it like
(int *arr4[8])
as well, but seems like this is not valid in C.
这不是 - 语法不允许。
int (*arr5[8])[8]
Not sure, but I presume this is something like an array of pointers to an array of integers.
准确地说,arr5
是指向int
的8元素数组的指针的8元素数组。从图形上看,它看起来像这样:
+---+ +---+---+---+---+---+---+---+---+
arr5: | | arr5[0] ----------> | | | | | | | | |
+---+ +---+---+---+---+---+---+---+---+
| | arr5[1] --------+
+---+ | +---+---+---+---+---+---+---+---+
| | arr5[2] ------+ +-> | | | | | | | | |
+---+ | +---+---+---+---+---+---+---+---+
... |
| +---+---+---+---+---+---+---+---+
+---> | | | | | | | | |
+---+---+---+---+---+---+---+---+
你会将每个元素索引为 (*arr5[i])[j]
- 你不想索引到每个 arr5[i]
,你想索引到每个 arr5[i]
点至。声明者预先告诉你这一点——你不必自己去弄明白。声明符的结构反映了表达式的结构。
请注意,此声明不会创建 int
的 8 元素数组 - 它 仅 创建一个 8 元素指针数组。您可能需要为每个要指向的 arr5[i]
动态分配内存,例如:
for ( size_t i = 0; i < 8; i++ )
arr5[i] = malloc( sizeof *arr5[i] ); // sizeof *arr5[i] == sizeof (int [8])
或者已经声明了一堆数组:
int foo[8];
int bar[8];
int bletch[8];
...
int (*arr5[8])[8] = { &foo, &bar, &bletch, ... };