请通俗解释C语言中declarator与direct-declarator的区别及语法疑问
在K&R《C程序设计语言(第二版)》第122页的语法定义里,declarator(声明符)和direct-declarator(直接声明符)是C语言类型声明的核心语法单元,两者的区别可以用**“基础单元”和“扩展单元”**来直白理解:
什么是direct-declarator?为什么叫“direct”?
它是声明符的最基础、最“直接”的形态——直接绑定到标识符(变量/函数的名字),没有任何额外的类型修饰(比如指针*、数组[]、函数()这些属性)。根据书中第225页的说明:
其中direct-declarator是标识符或带括号的标识符。特别需要注意的是,它不能通过typedef来实现函数类型。
举两个典型的direct-declarator例子:
- 纯标识符:
x(比如int x;里的x) - 带括号的标识符:
(x)(比如int (x);,本质和x一致,括号仅用来调整语法优先级)
它的“direct”就体现在:直接对应到程序中能直接引用的名字,没有中间的类型修饰层。
declarator和direct-declarator的关系
declarator是direct-declarator的扩展形式——你可以在direct-declarator的基础上,叠加一层或多层类型修饰,得到完整的declarator。换句话说,所有的declarator最终都要以direct-declarator为“根”,因为你总得有一个具体的名字,才能给它加指针、数组、函数这些属性。
举几个对比例子:
| 完整声明 | declarator部分 | 对应的direct-declarator | 说明 |
|---|---|---|---|
int x; | x | x | 此时declarator就是direct-declarator |
int *x; | *x | x | 在direct-declarator前加指针修饰* |
int x[10]; | x[10] | x | 在direct-declarator后加数组修饰[10] |
int (*x)[10]; | (*x)[10] | x | 嵌套修饰:先给x加指针,再整体加数组属性 |
int x(int); | x(int) | x | 在direct-declarator后加函数参数列表 |
关于“间接”的误解
你提到的“declarator是间接的”其实不准确——不是“间接”,而是declarator是包含了direct-declarator和额外类型信息的完整声明单元。direct-declarator是“原子”,declarator是用这个原子组合出来的“分子”,不存在“间接”的属性,只是语法层级上的包含关系。
另外补充书中提到的typedef限制:如果用typedef定义了一个函数类型(比如typedef int func();),然后写func x;,这里的x并不是direct-declarator——因为func已经封装了函数类型的属性,此时x是被typedef包装后的declarator,不符合“只能是标识符或带括号的标识符”的要求。
内容的提问来源于stack exchange,提问作者Joshua Ginn

