当使用 typedef 和附加限定符时,参数列表的解析如何工作?它的工作方式是否类似于文本替换,类似于#define?
\n例子:
\ntypedef struct Parameters_t * Parameters_pot;\nf(const Parameters_pot pars)\xc2\xa0\nf(Parameters_pot const pars)\xc2\xa0\nRun Code Online (Sandbox Code Playgroud)\n两个函数声明中参数列表中的“const”限定符是否与数据类型相关,这意味着指针指向常量结构?\n或者“const”的位置是否重要,并且在第一个函数声明中“const” ' 意味着结构体对象是常量,而在第二个声明中则意味着指针是常量?
\n它不是文本替换。这正是为什么将指针或数组隐藏在 a 后面typedef被认为是非常糟糕的做法的原因。这里的两个例子都相当于:
f(struct Parameters_t * const pars)
自从有人提出要求后,我们才尝试解释一下正式的律师语言:
C17 6.7.8 规定 typedef 的形式为typedef T type_ident;其中type_ident是类型名称“其类型由声明说明符指定T”。说明符复数。为了理解这一点,我们必须回到关于“声明符”和“声明说明符”的 6.7 和 6.7.6。
6.7.6 说每个声明都可以说由T D1声明T说明符和D1声明符组成。
“声明说明符”是您可以在声明中的标识符前面编写的所有内容,包括存储类说明符(static等)和类型限定符(const等),当然还有类型说明符(int等)。其中几个可以选择存在于同一声明中。
除了存储类说明符之外,存储类说明符作为一种特殊情况永远不能相互组合(6.7.1)。碰巧,它typedef被视为存储类说明符,因此我们不能static在typedef.
“声明符”包含标识符以及数组符号等。它可以选择包含*for 指针。这里重要的部分是*属于声明者。
正式语法(6.7.6)如下:
声明符:
指针opt直接声明符
...
指针:
*类型限定符列表opt
回到typedef T type_ident;,然后是T属于该类型的所有内容,包括使用的任何限定符、指针语法、数组语法等。
因此,我们应该编写类似const T, then 的const内容来应用于整个类型T。现在,如果我们有“T”,例如const int*“指向 const int 的指针”,那么const T将创建一个const int* const“指向 const int 的 const 指针”。
如果T是一个函数,那么它将尝试声明一个无效的“const 函数”。等等。
因此,对于您的示例typedef struct Parameters_t * Parameters_pot;,const应用于类型struct Parameters_t *。
因此f(const Parameters_pot pars)相当于f(struct Parameters_t * const pars).
f(Parameters_pot const pars)也具有相同的等效含义,原因与int const和const int等效 - 大多数时候未指定声明说明符可能出现的顺序。