无法在 switch case 中声明变量

Can't declare variable in switch case

#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:; 我可以编译我的代码。

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

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

看到N15706.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表达式和空语句中定义),它是一个语句,并且因此它是允许的。

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

在标签后放置空语句

case 4:;

你让标签现在不在声明之前。

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

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

What is the problem and why ; fix that?

问题正是错误消息所说的。你的 case 4: 是一个标签。标签标识 immediately-following 语句 ,因此必须紧接在语句之前。 int res = 1; 等声明不是语句。

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

话虽如此,我认为分号解决方案的风格很差。我还认为声明一个变量,其封闭块是 switch 的主体是一种糟糕的风格,而且这种风格也会以其他方式咬你。考虑将 res 的声明移到 switch ...

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

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

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

.