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

nob*_*alG 2 c++ case switch-statement

今天,当我试图写一个代码只是添加和减去两个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;
}
Run Code Online (Sandbox Code Playgroud)

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

  1. 我的困惑是关于error......
  2. case......中的括号要求

(我知道我没有使用新的编码约定,例如<iostream>,std命名空间等等,因为我已经在turbo c ++编译器中编写了它,因此谦虚地请求答案)

Set*_*gie 17

switch语句只是一堆标签,goto由编译器完成,具体取决于switch测试内部事物的值.

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

int a;
// can use a now
Run Code Online (Sandbox Code Playgroud)

但是,在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
Run Code Online (Sandbox Code Playgroud)

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

大括号解决了这个问题,因为它们使变量成为局部变量,因此它在后续的cases 中不存在.它只有在case输入特定内容时才会被创建,如果你忘记了一个break并且控制权落到下一个case,那么结尾就会}结束范围并导致变量被销毁,所以它不能从下一个访问case,并且初始化不能是跳过.

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


Kei*_*son 5

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

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

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

编辑:是的,我认为这是问题所在.在现代C++中,您的代码是可以的,因为循环变量的范围是循环本身.显然,Turbo实现了一种非常古老的语言版本,因此您的变量a可以一直显示在switch语句的底部.for用花括号括住每个循环应该避免警告:

{
    for (int a = 0; a <= 1; a++) {
        for (int b = 0; b <= 1; b++) {
            mat3[a][b] = mat1[a][b] + mat2[a][b];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

编辑3:编译器警告这一点的原因是,即使它看起来i总是在使用前初始化,你原则上可以参考icase 2:节,绕过初始化.(同样,这仅适用于旧规则.)

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

switch (choice) {
    case 1: {
        ...
        break;
    }
    case 2: {
        ...
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Fre*_*son 5

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;
}
Run Code Online (Sandbox Code Playgroud)

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