Switch-case 內定義變量的問題
這個問題需要分開討論,C 語言和 C++ 的標准定義是不同的。
C++
int Caset(int a) {
switch (a) {
case 1:
int b = 1;
std::cout<<"a==1: "<<b<<std::endl;
break;
case 2:
b = 2;
std::cout<<"a==2: "<<b<<std::endl;
break;
}
}
編譯報錯信息為
simple.cc:35:9: error: cannot jump from switch statement to this case label
case 2:
^
simple.cc:32:17: note: jump bypasses variable initialization
int b = 1;
^
也就是說,跳到 case2 的這個地方,忽略了對於 b 這個變量的初始化,這個很直觀,就是在這里我找不到 b。
那么如果改成
int Caset(int a) {
switch (a) {
case 1:
int b;
b = 1;
std::cout<<"a==1: "<<b<<std::endl;
break;
case 2:
b = 2;
std::cout<<"a==2: "<<b<<std::endl;
break;
}
}
順利成功,沒有報錯,如果 a 為 2,那么輸出 b 也是 2,說明邏輯沒有問題。那么問題來了,b 在前面聲明,為什么后面可以用到呢,因為 switch-case 的邏輯控制就是用 label 來標記跳轉的,而不是別的復雜的邏輯控制,所以 b 的作用域是在整個 switch 的花括號內,關於這個問題見知乎討論請教switch內部的變量定義問題。
C 語言
上面兩種寫法統統出錯,
void Caset(int a) {
switch (a) {
case 1:
/* one style */
int b;
b = 1;
/* another style */
int b = 1;
printf("1: %d", b);
break;
case 2:
b = 2;
printf("2: %d", b);
break;
}
}
兩種寫法都錯
First style:
main.c:12:13: error: expected expression
int b;
^
main.c:13:13: error: use of undeclared identifier 'b'
b = 1;
^
Another style:
ttt.c:11:13: error: expected expression
int b = 1;
^
意思是說,此處需要一個表達式(expression),而不是一個變量聲明初始化。有一個很黑客的做法,如下:
void Caset(int a) {
switch (a) {
case 1:
;
int b = 1;
// b = 1;
printf("1: %d \n", b);
break;
case 2:
b = 2;
printf("2: %d \n", b);
break;
}
}
這個很不能理解了,其實也就是說保證 case 后面跟着的確實是 expression 即可。考慮一下 C++ 代碼出現的問題:跳過變量的聲明?C 語言中同樣跳過,但是編譯器不認為這個是錯誤,而且邏輯上面也是沒有問題的,在后面的 case 中可以正常給變量賦值,但是如果 case2 中,我不是給 b 賦值,而是直接訪問 b,那返回的數值就是一個隨機的錯誤的數據了,我在我的電腦上使用 gcc 編譯,若直接讀取數據,得到的是 0,當然編譯通過,連警告都沒有。
總結起來就是:
- C 編譯器允許一個 case 使用另一個 case 后聲明定義的變量,但是 C++ 語法不允許這個
- C 不允許 case 后面緊跟聲明或定義,只允許表達式(expression); C++ 對這個沒有限制
通用解法
當然我認為這樣的代碼可讀性差,比較好的做法可以是將聲明變量的事情放在頭上做。
void Caset(int a) {
switch (a) {
int b;
case 1:
b = 1;
// b = 1;
printf("1: %d \n", b);
break;
case 2:
b = 2;
printf("2: %d \n", b);
break;
}
}
但是要留心, switch 和 case 之前那塊地方也就只能寫寫這樣的聲明,寫別的表達式,賦值啊什么的,統統是不會生效的。
參考:
Why can't variables be declared in a switch statement?這個鏈接中我個人比較推薦 AnT 的回答,講清楚了問題的原因和解決方案的原理