C语言 C 错误:int 之前的预期表达式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22419790/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 10:53:28  来源:igfitidea点击:

C error: Expected expression before int

csyntax-errorconditional-statementsvariable-declaration

提问by MsPillai

When I tried the following code I get the error mentioned.

当我尝试以下代码时,我收到了提到的错误。

if(a==1)
  int b =10;

But the following is syntactically correct

但以下在语法上是正确的

if(a==1)
{
   int b = 10;
}

Why is this?

为什么是这样?

回答by sheu

This is actually a fairly interesting question. It's not as simple as it looks at first. For reference, I'm going to be basing this off of the latest C11 language grammar defined in N1570

这实际上是一个相当有趣的问题。这并不像乍一看那么简单。作为参考,我将基于N1570 中定义的最新 C11 语言语法

I guess the counter-intuitive part of the question is: if this is correct C:

我想这个问题的反直觉部分是:如果这是正确的 C:

if (a == 1) {
  int b = 10;
}

then why is this not also correct C?

那么为什么这不也是正确的C?

if (a == 1)
  int b = 10;

I mean, a one-line conditional ifstatement should be fine either with or without braces, right?

我的意思是,单行条件if语句无论有没有大括号都应该没问题,对吧?

The answer lies in the grammar of the ifstatement, as defined by the C standard. The relevant parts of the grammar I've quoted below. Succinctly: the int b = 10line is a declaration, not a statement, and the grammar for the ifstatement requires a statement after the conditional that it's testing. But if you enclose the declaration in braces, it becomes a statement and everything's well.

答案在于ifC 标准定义的语句的语法。我在下面引用的语法的相关部分。简而言之:该int b = 10行是一个声明,而不是一个语句,并且该语句的语法if要求在它正在测试的条件之后有一个语句。但是如果你把声明括在大括号中,它就变成了一个声明,一切都很好。

And just for the sake of answering the question completely -- this has nothing to do with scope. The bvariable that exists inside that scope will be inaccessible from outside of it, but the program is still syntactically correct. Strictly speaking, the compiler shouldn't throw an error on it. Of course, you should be building with -Wall -Werroranyways ;-)

只是为了完全回答这个问题——这与范围无关。b存在于该范围内的变量将无法从其外部访问,但该程序在语法上仍然是正确的。严格来说,编译器不应该在上面抛出错误。当然,-Wall -Werror无论如何你都应该构建;-)

(6.7)声明:
            声明说明符 init-declarator-list opt  
            static_assert 声明

(6.7) init-declarator-list :
             init-declarator 
            init-declarator-list  ,  init-declarator

(6.7) init-declarator :
             declarator 
            declarator  =  initializer

(6.8)语句标记语句
            复合语句
            表达式语句
            选择语句
            迭代语句
            跳转语句

(6.8.2)复合语句:
             {  block-item-list opt  }

(6.8.4) selection-statement :
             if( 表达式 ) 语句
            if( 表达式 ) 语句 else 语句
            switch( 表达式 ) 语句

回答by Pranit Kothari

{ }-->

{ }-->

defines scope, so if(a==1) { int b = 10; }says, you are defining int b, for {}- this scope. For

定义范围,所以if(a==1) { int b = 10; }说,你正在定义 int b,对于 {}- 这个范围。为了

if(a==1)
  int b =10;

there is no scope. And you will not be able to use banywhere.

没有范围。而且您将无法在b任何地方使用。

回答by user3422531

By C89, variable can only be defined at the top of a block.

通过 C89,变量只能在块的顶部定义。

if (a == 1)
    int b = 10;   // it's just a statement, syntacitially error 

if (a == 1)
{                  // refer to the beginning of a local block 
    int b = 10;    // at the top of the local block, syntacitially correct
}                  // refer to the end of a local block

if (a == 1)
{
    func();
    int b = 10;    // not at the top of the local block, syntacitially error, I guess
}