C 类型符号表示法

3

我一直对C类型符号的工作原理有些困惑。 我无法访问Google,而Bing的搜索结果令人失望。

例如:int *(*)[]是什么意思?我已经知道它是指向整数指针数组的指针(我想),但为什么呢?特别是,我不明白方括号的作用; 是的,int **[]将是指向指针的指针数组,但为什么()会改变它?


4
尝试cdecl.org:有趣的交互式声明体验。 - pmg
1
..并在中间添加一个标识符,例如int *(*name)[] - KamilCuk
2
可以作为函数原型的一部分:void foo(int *(*)[]); - pmg
2
@KamilCuk 这并不是无效的,它是指向不完整类型数组的指针。甚至有一些罕见的用例可以使用这样的指针:函数或宏接受通用大小的数组。因为不完整项类型的数组与相同项类型的完整数组兼容,指向它们的指针也是如此。 - Lundin
2
#define IS_INT_ARRAY(x) _Generic(&(x), int(*)[]: true, default: false)为例。 - Lundin
显示剩余3条评论
1个回答

5
阅读这种类型的表达式时,可以在心里加上一个变量名,将其转换为有效的声明。然后从内向外阅读,就像阅读C语言中的所有变量声明一样。
int **[]   ->   int **a[];

a[]         //[] has higher precedence than *, so `a` is an array
*a[]        //this array contains pointers
**a[]       //which dereference to pointers
int **a[];  //which dereference to int

因此,int**[]是指向指向int的指针的指针数组的类型。

对于另一种类型,我们得到:

int *(*)[]   ->   int *(*a)[];

*a            //a is a pointer
(*a)          //(precedence control, only)
(*a)[]        //which dereferences to an array
*(*a)[]       //which contains pointers
int *(*a)[];  //which dereference to int

因此,int*(*)[]是指向指针数组的指针类型。

正如您所看到的,括号的作用是在 [] 之前选择第一个 * 运算符。后者具有更高的优先级,因此如果需要指向数组的指针,则需要引入括号。


有三个运算符与类型声明相关,了解它们的优先级很重要:

High precedence:
[]    array subscript declares an array
()    function call declares a function

Low precedence:
*     dereference operator declares a pointer

由于 * 的优先级低于 ()[],因此您需要添加额外的括号来声明指向数组或函数的指针。
int *a[];    //array of pointers, as a cast: `(int*[])`
int (*a)[];  //pointer to an array, as a cast: `(int(*)[])`

int *a();    //function returning a pointer, as a cast: `(int*())`
int (*a)(); //pointer to a function returning an `int`, as a cast: `(int(*)())`

一旦你理解了这个原则,C语言中的任何类型表达式都不会再让你感到困惑。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接