无法在切换情况下声明变量

时间:2020-09-29 13:23:15

标签: c switch-statement label declaration

#include<stdio.h>

void main()
{
    int a = 4;
    switch (a)
    {
        case 4:
            int res = 1;
            printf("%d",res);
        break;

    }
}

当我用gcc编译这段代码时出现错误

root@ubuntu:/home/ubuntu# gcc test.c -o t
test.c: In function ‘main’:
test.c:9:4: error: a label can only be part of a statement and a declaration is not a statement
    int res = 1;

但是当我像;那样添加case 4:;时,我可以编译我的代码。

问题出在哪里,为什么;解决了这个问题?

3 个答案:

答案 0 :(得分:8)

与C ++相反,在C语言中,声明不是语句,标签只能在语句之前。

在标签后放置一个空语句

case 4:;

您使标签现在不在声明之前。

另一种方法是在标签后使用复合语句,并将声明放置在复合语句中,例如

    case 4:
    {  
        int res = 1;
        printf("%d",res);
        break;
    }

答案 1 :(得分:6)

问题出在您的错误消息中:标签只能附加到语句中,而声明不是语句。

参见N1570 6.8.2复合语句,分别列举了declarationstatement,这表明它们是不同的东西。

Syntax
1     compound-statement:
          { block-item-listopt }

      block-item-list:
          block-item
          block-item-list block-item

      block-item:
          declaration
          statement

;中的case 4:;是一个空语句(在N1570 6.8.3表达式和空语句中定义),它是一个语句,因此可以使用。

答案 2 :(得分:3)

问题是什么,为什么;解决这个问题?

问题就出在错误消息上。您的case 4:是标签。标签标识紧随其后的声明,因此必须紧接在语句之前。诸如int res = 1;之类的声明不是语句。

另一方面,添加分号会创建一个空语句,顾名思义,该语句是一个语句,因此可以被标记。这就是为什么它可以解决问题。

话虽如此,我认为分号解决方案的风格差。我还希望将一个变量的封闭样式声明为switch的主体声明为较差的样式,并且该变量也可以用其他方式咬住您。考虑将res的声明移到switch之外...

int a = 4;
int res = 1;
switch (a) {
    case 4:
        printf("%d",res);
    break;
}

...或将其包含在内部块中(这是 compound语句,因此可以被标记)...

int a = 4;
switch (a) {
    case 4: {
        int res = 1;
        printf("%d",res);
        break;
    }
}