【问题标题】:Declarators semantics in C99C99 中的声明符语义
【发布时间】:2014-11-21 17:31:08
【问题描述】:

根据 ISO/IEC 9899:1999 6.7.5 §2,

每个声明器声明一个标识符,并断言 当同一操作数 形式作为声明符出现在表达式中,它指定一个函数或对象 声明说明符指示的范围、存储期限和类型。

我不知道为什么一个表达式突然出现在声明符语义中。你能给我一些例子来帮助我理解其中的含义吗?

【问题讨论】:

    标签: c c99 c11


    【解决方案1】:

    假设你声明:

    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?

    C -- Accessing a non-const through const declaration

    【讨论】:

    • 我在你的例子中看不到任何表达。这些与表达式有何联系?
    【解决方案2】:

    假设你有声明

    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
    

    表示一个函数指针数组,因为这就是我们可以应用后缀[] 并取回正确的类型。

    很有趣,不是吗;)

    【讨论】:

    • 你的例子很容易理解。衷心感谢您!
    【解决方案3】:

    这就是说,给定一个类似的声明

    const int a = 5; // declaration
    

    然后是 操作数 a 在表达式中

    x = a + b
    

    在同一范围内具有类型const int

    【讨论】:

    • 这是一个简单的例子,因为声明符只是一个标识符
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 2012-02-28
    • 2012-05-28
    相关资源
    最近更新 更多