请求解释C 2018标准6.7.6.1第1款中的指针声明规则
拆解C标准中指针声明的规则(C2018 6.7.6.1 1)
嘿,我太懂你读这段标准时的崩溃感了——C标准的官方措辞简直是故意绕弯子!别担心,咱们用实际代码例子一步步拆解,把这个晦涩的条款掰碎了说。
首先先把标准原文贴出来,方便对照:
若在声明“T D1”中,D1的形式为* type-qualifier-list opt D,且在声明“T D”中为标识符ident指定的类型是“derived-declarator-type-list T”,则为标识符ident指定的类型是“derived-declarator-type-list type-qualifier-list pointer to T”。对于列表中的每个类型限定符,ident都是一个带有该限定符的指针。
先搞懂条款里的几个核心术语
先把这些抽象的名词翻译成人话:
- T:声明里的基础类型,比如
int、char这种 - D1:整个声明符(就是变量名和前面的指针/数组/函数修饰部分)
- type-qualifier-list_opt:可选的类型限定符,就是
const、volatile、restrict这些,可加可不加 - derived-declarator-type-list:可以理解为“修饰基础类型的一串描述”,比如“array of 5”、“pointer to”、“function returning”这类
用简单例子套规则
咱们从最基础的指针声明开始:
int *p;
对应条款里的各个部分:
- T是
int - D1是
*p,也就是*(没有type-qualifier-list) + D(p) - 声明“T D”就是
int p;,这里标识符p的类型是int(derived-declarator-type-list是空,因为没有额外修饰) - 按照规则推导:
p的类型 = 空的derived-declarator-type-list + 空的type-qualifier-list + pointer to int → 也就是int *,完全符合我们平时的认知。
加类型限定符的情况
再看带const的指针声明,比如:
int *const p;
对应条款:
- T是
int - D1是
*const p,也就是*+ type-qualifier-list(const) + D(p) - 声明“T D”是
int p;,类型是int - 推导结果:
p的类型 = 空的derived-declarator-type-list +const+ pointer to int → 也就是int *const,意思是指针本身是const的——你不能让p指向别的地址,这就是条款最后那句“对于列表中的每个类型限定符,ident都是一个带有该限定符的指针”的意思:限定符是修饰指针本身的,不是修饰指针指向的内容。
复杂多层指针的例子
再搞个复杂点的,比如:
int *const *volatile q;
咱们递归套用规则:
- 先看内层的
int *volatile q;:- T是
int,D1是*volatile q,D是q - 推导得
q的类型是volatile pointer to int(derived-declarator-type-list就是volatile pointer to)
- T是
- 再套外层的
*const:- 现在T还是
int,D1是*const *volatile q,D是*volatile q - 根据规则,
q的类型 = 原来的derived-declarator-type-list(volatile pointer to) +const+ pointer to int → 也就是const pointer to volatile pointer to int,对应代码里的int *const *volatile q;
- 现在T还是
总结一下
这个条款本质上是指针类型的递归定义规则——不管是单层指针还是嵌套多层的指针,只要你在声明符前面加*和可选的限定符,就把原来的类型升级成“带有这些限定符的指针,指向原来的类型”。C标准用这种抽象的描述,是为了能覆盖所有可能的复杂声明场景,避免遗漏。
内容的提问来源于stack exchange,提问作者Michael Munta
相关产品推荐
相关产品推荐

