【问题标题】:Syntax: Single statement in function declaration语法:函数声明中的单个语句
【发布时间】:2011-07-07 14:37:41
【问题描述】:

在C编程语言中,在单条语句的情况下可以省略代码块,例如:

if(1) exit();

现在,这是否仅适用于条件句? 为什么这在函数的情况下无效:

void f(int a) exit();

【问题讨论】:

  • 因为标准是这么说的?
  • 从未尝试过,但我想,如果不允许,这只是语法问题,也许是遗留问题:一旦你写了 void f(a) int a; { ... },所以需要 { } 来标记参数类型声明块的结束...也许...
  • 谢谢,我知道旧的函数语法,但这也意味着编译器能够正确解析它......
  • 编译器能够正确解析(至少 gcc 可以)。
  • 查看这个相关问题,询问关于 C# 的相同问题:stackoverflow.com/questions/6016654/…

标签: c syntax


【解决方案1】:

这是 C 语法的一个特性。在BNF 中,函数定义类似于

FUNC_DEF ::= TYPE IDENTIFIER "(" PARAM_LIST ")" BLOCK

while 语句是

STATEMENT ::= (EXPRESSION | DECLARATION | CONTROL | ) ";" | BLOCK
BLOCK ::= "{" STATEMENT* "}"

(简化以允许混合声明和语句,C++ 允许但 C 不允许),if 语句是

CONDITIONAL ::= "if" "(" EXPRESSION ")" STATEMENT

暂时省略else 部分。

这样做的原因是,否则,您可以编写函数

void no_op() {}

作为

void no_op();

但后一种语法已经用于表示声明。

【讨论】:

  • 我认为从 C 解析器的角度来看这是一个内部问题。因为我在解析器的第二个语句中没有看到任何矛盾。但无论如何 +1
  • 谢谢!这正是我一直在寻找的答案,你提醒我为什么我喜欢 CS!
  • int no_op() {}no_op() 看起来更混乱。
  • 虽然你可以禁止 void no_op(); 定义的语法,例如FUNC_DEF ::= TYPE IDENTIFIER "(" PARAM_LIST ")" (BLOCK|STATEMENT)。但这会让新手甚至学徒感到困惑。
  • @phresnel:我更新了STATEMENT 规则以更准确地反映C 语法; ; 本身就是一个有效的声明,所以你的建议是行不通的。
【解决方案2】:
  • 条件语句的语法是这样的:

    if(expression) statement
    
  • 复合语句就是语句。

  • compound statement 定义为

    { zero or more statements }
    
  • 函数定义的语法是这样的

     function_declaration compound_statement
    
  • 因此,根据定义,函数体必须是复合语句并且具有{}

  • QED :)

【讨论】:

    【解决方案3】:

    有一种非常古老的 C 方言,即 K&R C。在这种方言中,函数声明可能如下所示:

    fun_a(a,b)
    char a;
    float b;
    {
            fun_b(b,a);
    }
    

    我认为如果没有{},解析它会太难。

    【讨论】:

    • 这可能是历史原因,+1,但还有一个原因是 ANSI C 中的语法没有改变。
    猜你喜欢
    • 2012-04-21
    • 1970-01-01
    • 2011-07-18
    • 2020-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-07
    • 1970-01-01
    相关资源
    最近更新 更多