根据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);
语义
每个声明符声明一个标识符,并断言当与声明说明符具有相同形式的操作数在表达式中出现时,它指示了由声明说明符所指明的具有作用域、存储期和类型的函数或对象。
评论
表达式中标识符的形式可能与声明符中的形式相同。例如,当需要指向x的值时,声明符* x将在表达式中具有此形式,当引用数组y的元素时,声明符y[2]将在表达式中具有此形式。声明中的声明符声明了标识符。还有一种特殊的声明符,即抽象声明符,它不声明标识符。
我理解上述内容为:
如果您声明:
int *x;
*x
时,*x
的类型为int
。如果您声明:static int const *x;
*x
时,*x
的类型为static int const
。
其他参考资料
静态变量声明(C语言)
在C语言中,[ ]也是一个声明符吗?(用于参数声明)
C语言--通过const声明访问非const内容
假设你有如下声明:
int foo[42];
声明部分是foo[42]
。每当一个同样形式的东西(即由foo
后跟[
后跟表达式后跟]
组成)出现在表达式中(并且声明在作用域内),该子表达式的类型将是声明的类型int
。
换句话说:就语法而言,像这样的声明
int *bar;
这段文字的意思是,它并没有声明bar
为int *
类型,而是声明了*foo
为int
类型。
举个更复杂的例子,看下面这个声明:
float (*op[42])(float, float);
c = (*op[i])(a, b);
*op[i]
必须具备函数类型(我们忽略函数设计符号衰减为相应的指针类型和通过后缀()
调用函数实际上是在指针上进行而不是在设计符号上进行的事实)。
这反过来意味着
op[i]
op
将函数指针数组表示为这是我们可以应用后缀[]
并返回正确类型的方式。
很有趣,不是吗 ;)
这句话的意思是,假设有一个类似于以下声明的语句
const int a = 5; // declaration
在像这样的表达式中,操作数 a
然后
x = a + b
在同一作用域中具有类型为const int
。