编译器如何理解指针和数组的声明[关闭]

Posted

技术标签:

【中文标题】编译器如何理解指针和数组的声明[关闭]【英文标题】:How does compiler understand the declaration of pointers and arrays [closed] 【发布时间】:2017-06-12 03:03:06 【问题描述】:

当我对指针数组和指针数组感到困惑时,我想到了这个问题,尽管我现在已经弄清楚了如何从字面上区分它们。

但我仍然对编译器如何理解指针声明感到困惑。例如,有没有像int* 这样的类型?

int *p;   // a common pointer declaration

具体来说,编译器是如何理解前一句的呢?先把p当作一个指针,然后找到指向的对象是int?或者查找用户声明了一个指向 int 的指针 int*,名为 p

面对指向数组的指针时,我更加困惑。

int (*p)[4]   //a pointer to an array of int[4]

这怎么理解?编译器是否将其视为int[4] *pint[4] 像我们在容器中那样工作的新类型)?以下案例中的类似问题。

int *p[4]    //an array-of-pointers

由于[]*之前,编译器是否首先理解p[4]并将p视为一个数组(元素类型未知),然后将元素类型指定为int*

【问题讨论】:

【参考方案1】:

声明的解析可以在当前标准的第 6.7.6 节中找到。它太大了,无法完整回顾,但简而言之,关于p 类型的规则以归纳 方式布局。在这些规则中,T 是普通类型(没有指针/数组等),D 是声明符:

    T * D 被定义为如果T D 中的D 的类型是“something of/to T”,那么D 的类型是“something of pointer to T"。

    T D[N](其中 N 可以是空白或其他各种东西)被定义为表示如果T D 中的D 的类型是“T”,那么D 是“T 的数组(维度为 N)的东西”。

因此,您可以看到每条规则都修改了之前应用该规则的结果,直到我们到达归纳的“结尾”,当D 是一个普通标识符时发生。

另外,T ( D ) 表示T D,而不是强制解析。

一些消息来源将声明描述为“由内而外”阅读,虽然这个归纳链实际上是“由外而内”发生的,但您需要进入然后回溯您的结果。尽管最终结果是相同的,但我们可能被教导作为人类阅读的方式与语言定义不同。


要使用您的一个示例,int *p[4]

规则 1 - 形式为 T * DT = intD = p[4]。由于T D 将是“int 的array[4]”(见下文),因此T * D 是“指向int 的指针的array[4]”。

在这一步我们分析了int q[4]

规则 2 - 格式为 T D[N]T = intD = q。这是“结束情况”,因为D 是一个普通标识符,所以这一步q 的类型是“int 的数组[4]”。

再举个例子,int (*p)[4]:

规则 2 - 格式为 T D[N],其中 T = intD = (*p)。因为T D 是“指向int 的指针”,那么T D[4] 是“指向int 的数组[4] 的指针”。

【讨论】:

这真的解决了我的问题。非常非常非常非常感谢!!!!!!!!!

以上是关于编译器如何理解指针和数组的声明[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

malloc如何在编译时和运行时处理? [关闭]

《C专家编程》数组和指针并不同--多维数组

从编译器角度分析数组名和指针的区别

使用 typedef、多维数组和指针时出现编译器错误

《C专家编程》数组和指针并不同--多维数组

数组名和指针能够等价的情况