关于switch中case语句中的大括号

时间:2011-08-12 18:20:54

标签: c++ switch-statement case

今天我正在尝试编写一个代码来添加&减去两个2 * 2矩阵,其中我使用了switch语句,我得到了一个错误在函数main()

中局部变量的旁路初始化
#include <iostream.h>
#include <conio.h>
#include <string.h>

int 
main()
{
    int mat1[2][2], mat2[2][2], mat3[2][2];

    cout << "Enter the elements in the first matrix";
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            cin >> mat1[i][j];
        }
    }

    cout << "\n\nEnter the elements of the second matrix";

    for (int k = 0; k < 2; k++) {
        for (int l = 0; l < 2; l++) {
            cin >> mat2[k][l];
        }
    }

    cout << "\n\nsaved......";

    int choice;
    cout << "\n\n\nFor adding these two matrices,press 1";
    cout << "\nFor subtracting these two matrices,press 2";
    cin >> choice;

    switch (choice) {
    case 1:

        cout << "The addition of the two matrices will yield";
        for (int a = 0; a <= 1; a++) {
            for (int b = 0; b <= 1; b++) {
                mat3[a][b] = mat1[a][b] + mat2[a][b];
            }
        }
        break;

    case 2:
        cout << "The subtraction of the two matrices will yield";
        for (int c = 0; c <= 1; c++) {
            for (int d = 0; d <= 1; d++) {
                mat3[c][d] = mat1[c][d] - mat2[c][d];
            }
        }
        break;
    }
    getch();
    return 0;
}

我还发现我可以通过将案例代码放入大括号中来消除此错误,现在,

  1. 我的困惑是关于error ...
  2. &安培; case ....
  3. 中括号的要求

    (我知道我没有使用新的编码约定,比如<iostream>,std命名空间等等,因为我已经在turbo c ++编译器中编写了它,所以要点回答是谦虚地要求)< / p>

3 个答案:

答案 0 :(得分:17)

switch语句只是一堆标签和编译器goto完成的,具体取决于switch测试中事物的值。

如果函数中有局部变量,那么在该变量声明之后的任何地方都可以使用它。例如:

int a;
// can use a now

但是,在switch语句中,如果您有一个局部变量:

case a:
    int a;
    break;
case b:
    // we can use a here because these cases are just labels used in a goto
    // i.e. the cases do *not* create a new scope

因此,当case中有变量时,变量存在于其下面的case中,但变量将不存在,因为初始化它的代码被case语句跳过。我很难解释,也许别人可以做得更好。

大括号解决了这个问题,因为它们使变量成为局部变量,因此它在后续case中不存在。只有在输入特定case时才会创建它,如果您忘记break并且控制权转到下一个case,则结尾}将结束范围和原因要销毁的变量,因此无法从下一个case访问它,并且不能跳过初始化。

所以请记住所有case的共享范围。这可能有助于您理解这一点。

答案 1 :(得分:5)

重新缩进代码并更改一些内容以便在我的系统上进行编译后,g ++会在没有警告的情况下编译代码。

我最好的猜测是它与for循环中声明的对象范围的旧规则有关(它曾经存在直到封闭范围的末尾;在现代C ++中它仅限于循环本身),但我不太确定。

为了帮助我们解决这个问题,请正确缩进代码,并向我们显示确切的错误消息,包括行号。如果错误显示“第42行:...”,请在您的来源中添加评论// this is line 42

编辑:是的,我认为这就是问题所在。在现代C ++中,您的代码是可以的,因为循环变量的范围是循环本身。显然,Turbo实现了该语言的一个非常旧的版本,因此您的变量aswitch语句的底部一直可见。将每个for循环括在大括号中应该避免警告:

{
    for (int a = 0; a <= 1; a++) {
        for (int b = 0; b <= 1; b++) {
            mat3[a][b] = mat1[a][b] + mat2[a][b];
        }
    }
}

EDIT2:或者更好的是,停止使用Turbo C ++并获得一个现代编译器。

EDIT3:编译器警告这一点的原因是即使i似乎在使用前始终被初始化,您原则上可以参考i部分中的case 2: ,绕过初始化。 (同样,这仅适用于旧规则。)

解决此问题的一种更简洁的方法可能是将每个case部分括在大括号中:

switch (choice) {
    case 1: {
        ...
        break;
    }
    case 2: {
        ...
        break;
    }
}

(或者,再次,获得一个现代编译器,除非你有充分的理由坚持使用Turbo C ++)。

答案 2 :(得分:1)

case块本身不是新范围。您在其中声明的任何变量对于switch语句的其余部分都是可见的。但在其他case块中,它是未初始化的。通过添加大括号,您可以创建一个新的范围,以便其他区块无法看到它。

例如:

switch (choice)
{
case 0:
    int a = 42;
    break;


case 1:
    std::cout << a << std::endl; // 'a' is uninitialized here
    break;
}


switch (choice)
{
case 0:
    {
        int a = 42;
        break;
    }


case 1:
    std::cout << a << std::endl; // error -- 'a' is not declared here
    break;
}

我在你发布的代码中没有看到这样的情况,但这就是错误信息的含义。