根据ISO/IEC 9899:19996.7.5§2,
每个声明符声明一个标识符,并声明当与表达式中出现的声明符形式相同的操作数出现在表达式中时,它指定一个函数或对象,其范围,存储持续时间和声明说明符指示的类型.
我不知道为什么表达式突然出现在声明符语义中.你能给我一些可以帮助我理解其含义的例子吗?
说你声明:
static int const i, j, k;
Run Code Online (Sandbox Code Playgroud)
这与:
static int const i;
static int const j;
static int const k;
Run Code Online (Sandbox Code Playgroud)
声明符static int const
说明符适用于所有标识符.
您还可以将该逻辑扩展到函数和函数指针.
static int i, (*fun1)(void), fun2(void);
Run Code Online (Sandbox Code Playgroud)
这与:
static int i;
static int (*fun1)(void);
static int fun2(void);
Run Code Online (Sandbox Code Playgroud)
至于表达部分中出现的内容,请参阅http://c0x.coding-guidelines.com/6.7.5.pdf上的一些评论.它说:
语义
每个声明符声明一个标识符,并声明当与表达式中出现的声明符形式相同的操作数出现在表达式中时,它指定一个函数或对象,其范围,存储持续时间和声明说明符指示的类型.
评论
表达式中标识符的形式可能与声明符中的形式相同.例如,当x指向的值是必需的时,声明符*x将在表达式中具有此形式,并且当引用数组y的元素时,声明符y [2]将在表达式中具有此形式.它是声明标识符的声明的声明者部分.有一种特殊的声明符,一个抽象声明符,它不声明标识符
我将上述解释为:
如果你声明:
int *x;
Run Code Online (Sandbox Code Playgroud)
并使用*x
在表达式的类型,*x
是int
.
如果你宣布
static int const *x;
Run Code Online (Sandbox Code Playgroud)
并使用*x
在表达式的类型,*x
是static int const
.
其他参考
说你有声明
int foo[42];
Run Code Online (Sandbox Code Playgroud)
声明符部分是foo[42]
. 每当表达式中出现相同形式(即foo
后跟[
表达式后跟]
)时(并且声明在范围内),该子表达式的类型将是声明的 type int
。
换句话说:就语法而言,像这样的声明
int *bar;
Run Code Online (Sandbox Code Playgroud)
也没有声明bar
是类型int *
,而是声明*foo
为类型int
。
有关更复杂的示例,请使用声明
float (*op[42])(float, float);
Run Code Online (Sandbox Code Playgroud)
在表达式中,相同形式的操作数可能如下所示
c = (*op[i])(a, b);
Run Code Online (Sandbox Code Playgroud)
根据引文,右侧的类型为float
。
这意味着
*op[i]
Run Code Online (Sandbox Code Playgroud)
必须具有函数类型(我们忽略了函数指示符衰减为相应的指针类型的事实,并且通过后缀调用的函数()
实际上适用于指针,而不是指示符)。
这反过来又意味着
op[i]
Run Code Online (Sandbox Code Playgroud)
必须表示一个函数指针,我们最终到达
op
Run Code Online (Sandbox Code Playgroud)
表示一个函数指针数组,因为我们可以[]
在其上应用后缀并返回正确的类型。
有趣,不是吗;)