你如何破译指针+数组的复杂声明?

时间:2009-10-01 00:08:18

标签: c++ arrays pointers

虽然我几乎一直使用std::vector,但我有兴趣尽可能多地了解指针。我在说什么的例子:

char* array[5]; // What does it mean?
// 1) pointer to an array of 5 elements!
// 2) an array of 5 pointers?

我对此声明的准确定义感兴趣。

7 个答案:

答案 0 :(得分:3)

不只是指针和数组:How to interpret complex C/C++ declarations

  

开始阅读来自的声明   最里面的括号,向右走,和   然后向左走。当你遇到   括号,方向应该是   逆转。一切都在   括号已被解析,跳出来   它的。继续直到整个   声明已被解析。

     

左右一个小变化   规则:当你开始阅读时   你是第一次申报   必须从标识符开始,并且   不是最里面的括号。

你的例子:

char* array[5];

是一个包含5个指向char的指针的数组。

答案 1 :(得分:3)

cdecl是一个很适合这种事情的程序。 (特别是当您将函数指针添加到混合中时!)

Type `help' or `?' for help
cdecl> explain char* foo[5]
declare foo as array 5 of pointer to char
cdecl> declare bar as array 5 of pointer to function (integer, integer) returning char
char (*bar[5])(int , int )

答案 2 :(得分:2)

很久以前,我从一篇杂志文章中学到了顺时针/螺旋规则。这是一篇描述该技术的在线文章:

这对我很有帮助,尽管我仍然很难与我偶尔遇到的一些基于模板的怪异声明作斗争。

答案 3 :(得分:2)

在C / C ++中读取类型的一般过程是:

  1. 标识最终类型,它可以是基本类型或typedef标识符,并且可以包含类型修饰符,例如const,volatile等。在您的示例中为“char”。
  2. 以与表达式相同的优先顺序将运算符应用于标识符。这些运算符可以是*(取消引用),[](索引)和()(调用函数)。
  3. 在语法的原始哲学中,您的示例将被写为“char * array [5]”,标识符为“array”,运算符为[](index),然后是*(取消引用)。

    声明然后读作合同“如果你按照这个顺序应用这些运算符,那么你得到一个最终类型的对象”。

    在你的情况下,完整的句子是“如果你索引变量”数组“,然后取消引用结果表达式,你得到一个字符”。

    你也可以这样认为“如果你索引变量”数组“,那么你得到一个对象,如果你取消引用它,你会得到一个字符”

    诀窍主要是跟踪[]和()的优先级高于*的事实。您可以使用括号来控制运算符顺序,就像使用正则表达式一样。

答案 4 :(得分:1)

char *是类型,你有一个包含5个数组的数组。

答案 5 :(得分:1)

[]的优先级高于*,这就是为什么它是一个指针数组,而不是相反。

答案 6 :(得分:1)

你总是从右到左读取指针,将'*'解释为指针。 例如char ** a [5]是指向字符指针的5个指针数组......