C++:在 switch 语句中构造数组

C++: Construct arrays inside a switch statement

本文关键字:数组 语句 switch C++      更新时间:2023-10-16

我正在尝试构造一个具有几种不同配置的数组,其中将随机选择一个。我首先尝试的代码是:

void createArray() {
    int* tileVals;
    int randInt = rand() % 3;
    switch (randInt) {
    case 0:
            int tileVals[] = {1,1,1,2,2,2,3,3,3};
            break;
    case 1:
            int tileVals[] = {1,1,1,1,2,2,3,3,3};
            break;
    case 2:
            int tileVals[] = {1,1,1,1,2,2,2,3,3};
            break;
    }
    // Do stuff with tileVals
}

但是我得到了编译器错误:

src/Board.cpp:67:7: error: redefinition of 'tileVals'
        int tileVals[] = {1,1,1,1,2,2,2,3,3};
src/Board.cpp:70:7: error: redefinition of 'tileVals'
        int tileVals[] = {1,1,1,2,2,2,2,3,3};
...

我接下来尝试:

void createArray() {
    int* tileVals;
    int randInt = rand() % 3;
    switch (randInt) {
    case 0:
            int case0[] = {1,1,1,2,2,2,3,3,3};
            tileVals = case0;
            break;
    case 1:
            int case1[] = {1,1,1,1,2,2,3,3,3};
            tileVals = case1;
            break;
    case 2:
            int case2[] = {1,1,1,1,2,2,2,3,3};
            tileVals = case2;
            break;
    }
    // Do stuff with tileVals
}

但这又返回了一个编译器错误:

src/Board.cpp:85:2: error: switch case is in protected scope
    case 6:
         ^
src/Board.cpp:82:7: note: jump bypasses variable initialization
    int case5[] = {1,1,1,2,2,3,3,3,3};
...

我知道我可以在每个 case 语句中都有一个 for 循环,然后将值分配给在 switch 语句之外创建的 tileVals 数组,但这似乎不是一种非常有效的方法。 有没有更好的方法?谢谢。

如果不在

后面的代码中修改tileVals的内容,可以按如下方式操作:

void createArray() {
    int * tileVals;
    int randInt = rand() % 3;
    int cases[][9] = { {1, 1, 1, 2, 2, 2, 3, 3, 3},
                       {1, 1, 1, 1, 2, 2, 3, 3, 3},
                       {1, 1, 1, 1, 2, 2, 2, 3, 3} };
    tileVals = cases[randInt];
    // Do stuff with tileVals
}
  1. 因此,您的第一个示例失败了,因为在 switch 语句中声明的所有变量都具有相同的作用域。所以你正在重新定义变量。
  2. 第二个示例失败,因为您正在访问超出范围的堆栈内存。

对此没有很好的解决方案...我可能会做:

void createArray() {
    static const int case0[] = {1,1,1,2,2,2,3,3,3};
    static const int case1[] = {1,1,1,1,2,2,3,3,3};
    static const int case2[] = {1,1,1,1,2,2,2,3,3};
    const int *tileVals = NULL;
    int randInt = rand() % 3;
    switch (randInt) {
    case 0:
            tileVals = case0;
            break;
    case 1:
            tileVals = case1;
            break;
    case 2:
            tileVals = case2;
            break;
    }
    // Do stuff with tileVals
}

如果你真的需要编辑tileVals的内容,那么我可能会在switch语句之前为tileVals分配内存,然后使用memcpy()

要在 case 语句中创建变量,必须将大小写括在大括号中。

switch(condition) {
case 0: {
    int x = 0;
    break;
}
}

第二个编译器错误可以用一个更简单的例子来解释:

void foo()
{
  goto end:
  int x = 0;
  end:
}

当我编译仅包含该函数的文件时,出现以下错误。

g++ -c -o test-33.o test-33.cctest-33.cc:在函数 'void foo()' 中:test-33.cc:5:7:错误:跳转到标签"结束" [-允许]test-33.cc:3:12:错误:从这里 [-允许]test-33.cc:4:11:错误:交叉初始化"int x"test-33.cc:6:5:错误:"}"标记之前的预期主表达式test-33.cc:6:5:错误:在"}"标记之前应为";"

这对我来说意味着,我们正在执行一个 goto 语句,该语句跳转变量x的初始化。您可以在end:之后引用x,即使绕过了x的初始化。

您在开关块中看到类似的错误case ...:因为语句是跳跃点,就像goto语句的跳跃点一样。