C语言变量声明中的括号有什么含义?

39

有人能解释一下这是什么意思吗?

int (*data[2])[2];

这个微软链接可能会有所帮助。(或者它可能会让你的大脑爆炸)解释更复杂的声明符 - Mark Ransom
5个回答

48

括号有什么作用?

在C语言中,方括号[]比星号*的优先级高。

以下是维基百科上的好解释:

为了将一个变量声明为数组指针,我们必须使用括号。这是因为在C语言中,方括号([])比星号(*)的优先级更高。因此,如果我们想声明一个指向数组的指针,我们需要提供括号来覆盖这一点:

double (*elephant)[20];
这声明了elephant是一个指针,它所指向的类型是一个包含20个双精度浮点数的数组。
要声明一个指向指针数组的指针,只需简单地组合这些符号。
int *(*crocodile)[15];

来源.

而你的实际情况:

int (*data[2])[5];

数据是一个由2个元素组成的数组。每个元素都包含指向5个整数数组的指针。

因此,在使用您的“数据”类型的代码中,您可以有:

int (*data[2])[5];
int x1[5];
data[0] = &x1;
data[1] = &x1;

data[2] = &x1;//<--- out of bounds, crash data has no 3rd element
int y1[10];
data[0] = &y1;//<--- compiling error, each element of data must point to an int[5] not an int[10]

完美答案! - J3STER

18

有一个非常酷的程序叫做“cdecl”,你可以在Linux/Unix上下载它,可能也可以在Windows上下载。你可以粘贴一个C(如果你使用c++decl,则是C++)变量声明,程序会用简单的语言把它解释出来。


1
以 @sixlettervariables 这样的名字,我猜你比我还更老派。请告诉我你还记得 Henry Spencer 的戒律吧? - Paul Tomblin
1
这是一个现在就可以使用的网站:https://cdecl.org/ - Pro Q

6
如果你知道如何在C语言中阅读表达式,那么你离阅读复杂声明只有一步之遥。
以下是待翻译内容:

这是什么意思?

char *p;

真正的意思是什么?它意味着*p是一个字符。这句话的含义是什么?
int (*data[2])[5];

意思是(*data[x])[y]是一个int类型(假设0 <= x < 2且0 <= y < 5)。现在,想一想这意味着什么。 data必须是...一个包含2个指向数组的指针...的数组,每个数组包含5个整数。

你不觉得这很优雅吗?你只是在声明表达式的类型。一旦你掌握了这一点,声明就再也不会让你感到害怕了!

"快速规则"是从变量名开始,向右扫描直到遇到),返回到变量名,向左扫描直到遇到(。然后“跳出”括号对,并重复这个过程。

让我们将其应用于一些荒谬的事情:

void **(*(*weird)[6])(char, int);

weird是一个指向包含6个指向函数的指针数组的指针,每个函数都接受一个char和一个int作为参数,并返回一个指向指向void的指针的指针。

既然你知道它是什么以及如何完成... 不要这样做。使用typedef将声明拆分成更易处理的块。例如:

typedef void **(*sillyFunction)(char, int);

sillyFunction (*weird)[6];

现在,使用 using 将名称映射到类型。 - IS4
现在,使用C++ :-P - IS4

-1
如果你有一个数组:
int myArray[5];
int * myArrayPtr = myArray;

这是完全合理的。没有方括号的myArray是一个指向int的指针。当你添加方括号时,就像你解引用了指针myArray。你可以这样写...

myArrayPtr[1] = 3;

这是非常合理的。在我看来,使用括号只会让事情变得更难读懂和理解。而且它们表明人们不理解指针、数组和指针算术运算,而编译器或链接器正是通过这些来进行转换。不过使用括号似乎可以进行边界检查。


-1

data[2] - 一个包含两个整数的数组

*data[2] - 指向一个包含两个整数的数组的指针

(*data[2]) -

(*data[2])[2] - 包含两个指向包含两个整数的数组的指针的数组。


1
第二个项目不是你所说的。除了缺少类型(你假设为整数),它是一个包含2个整数指针的数组。第三个不是C。第四个可能是正确的。 - Jonathan Leffler
嗯,我猜可能引号是一个同上号。我仍然认为解释有些欠缺。 - Jonathan Leffler

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