【发布时间】:2014-11-21 17:31:08
【问题描述】:
根据 ISO/IEC 9899:1999 6.7.5 §2,
每个声明器声明一个标识符,并断言 当同一操作数 形式作为声明符出现在表达式中,它指定一个函数或对象 声明说明符指示的范围、存储期限和类型。
我不知道为什么一个表达式突然出现在声明符语义中。你能给我一些例子来帮助我理解其中的含义吗?
【问题讨论】:
根据 ISO/IEC 9899:1999 6.7.5 §2,
每个声明器声明一个标识符,并断言 当同一操作数 形式作为声明符出现在表达式中,它指定一个函数或对象 声明说明符指示的范围、存储期限和类型。
我不知道为什么一个表达式突然出现在声明符语义中。你能给我一些例子来帮助我理解其中的含义吗?
【问题讨论】:
假设你声明:
static int const i, j, k;
同理:
static int const i;
static int const j;
static int const k;
声明符说明符 static int const 应用于所有标识符。
您还可以将该逻辑扩展到函数和函数指针。
static int i, (*fun1)(void), fun2(void);
等同于:
static int i;
static int (*fun1)(void);
static int fun2(void);
就出现在表达式中部分而言,http://c0x.coding-guidelines.com/6.7.5.pdf 有一些评论。它说:
语义
每个声明符声明一个标识符,并断言当与声明符形式相同的操作数出现在表达式中时,它指定一个函数或对象,其范围、存储期限和类型由声明说明符指示。
评论
表达式中标识符的形式很可能与声明符中的形式相同。例如,当需要 x 指向的值时,声明符 * x 将在表达式中具有这种形式,而当引用数组 y 的元素时,声明符 y[2] 在表达式中将具有这种形式。它是声明标识符的声明的声明符部分。有一种特殊的声明器,抽象声明器,它不声明标识符
我将以上解释为:
如果你声明:
int *x;
并在表达式中使用*x,*x 的类型为int。
如果你声明
static int const *x;
并在表达式中使用*x,*x 的类型为static int const。
其他参考资料
Static Variable Declaration (C)
Is [ ] also a declarator (when used in parameter declaration) in C?
【讨论】:
假设你有声明
int foo[42];
声明符部分是foo[42]。每当表达式中出现相同形式的内容(即foo 后跟[ 后跟一个表达式,然后是])时(并且声明在范围内),该子表达式的类型将是声明的输入int。
换一种说法:就语法而言,像这样的声明
int *bar;
不将bar 声明为int * 类型,而是将*foo 声明为int 类型。
更复杂的例子,以声明为例
float (*op[42])(float, float);
在表达式中,相同形式的操作数可能如下所示
c = (*op[i])(a, b);
根据引用,右侧的类型为float。
这意味着
*op[i]
必须具有函数类型(我们忽略了这样一个事实,即函数指示符衰减为相应的指针类型和通过后缀() 调用的函数实际上适用于指针,而不是指示符)。
这反过来意味着
op[i]
必须表示一个函数指针,我们最终到达
op
表示一个函数指针数组,因为这就是我们可以应用后缀[] 并取回正确的类型。
很有趣,不是吗;)
【讨论】:
这就是说,给定一个类似的声明
const int a = 5; // declaration
然后是 操作数 a 在表达式中
x = a + b
在同一范围内具有类型const int。
【讨论】: