C99中的声明符语义

6
根据ISO/IEC 9899:1999 6.7.5 §2规定,每个声明符声明一个标识符,并断言当与声明符形式相同的操作数出现在表达式中时,它指示由声明说明符指定的作用域、存储期和类型的函数或对象。我不知道为什么表达式会突然出现在声明符的语义中。您能给我一些例子来帮助我理解其含义吗?
3个回答

5

假设你声明:

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其他参考资料 静态变量声明(C语言) 在C语言中,[ ]也是一个声明符吗?(用于参数声明) C语言--通过const声明访问非const内容

我在你的例子中没有看到任何表达式。这些与表达式有什么关联? - 김단영

5

假设你有如下声明:

int foo[42];

声明部分是foo[42]。每当一个同样形式的东西(即由foo后跟[后跟表达式后跟]组成)出现在表达式中(并且声明在作用域内),该子表达式的类型将是声明的类型int

换句话说:就语法而言,像这样的声明

int *bar;

这段文字的意思是,它并没有声明barint *类型,而是声明了*fooint类型。

举个更复杂的例子,看下面这个声明:

float (*op[42])(float, float);

在表达式中,同一形式的操作数可能看起来像这样。
c = (*op[i])(a, b);

根据引文,右侧应为 "float" 类型。
这意味着:
*op[i]

必须具备函数类型(我们忽略函数设计符号衰减为相应的指针类型和通过后缀()调用函数实际上是在指针上进行而不是在设计符号上进行的事实)。

这反过来意味着

op[i]

必须表示一个函数指针,最终我们到达
op

将函数指针数组表示为这是我们可以应用后缀[]并返回正确类型的方式。

很有趣,不是吗 ;)


您的示例非常容易理解。衷心感谢您! - 김단영

0

这句话的意思是,假设有一个类似于以下声明的语句

const int a = 5; // declaration

在像这样的表达式中,操作数 a 然后

x = a + b

在同一作用域中具有类型为const int


这是一个微不足道的例子,因为声明符只是一个标识符。 - Christoph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接