轉自:
http://blog.chinaunix.net/uid-27103408-id-3340702.html
http://www.xuebuyuan.com/2070170.html
switch是我們做條件選擇時,經常用到的一個語句。一直以來對於他的使用相信大家也都是得心應手,前幾天在linux下寫一個c++程序時遇到了這樣的一個問題,請看例子:
#include<iostream>
using namespace std;
int main()
{
int i;
cout<<"please input the value of i ---(0-9)"<<endl;
cin >> i;
switch(i)
{
case 0:
int j = 3;
cout << j <<endl;
break;
case 4:
case 1:
case 2:
break;
}
return 0;
}
不知道大家看出這個程序問題在什么地方沒有,一開始我是沒有感覺有什么不對的地方,后來編譯的時候就出現了問題:
testswitch.cpp:14:8: 錯誤: 跳轉至 case 標號 [-fpermissive]
testswitch.cpp:11:8: 錯誤: 跳過了‘int j’的初始化
testswitch.cpp:15:8: 錯誤: 跳轉至 case 標號 [-fpermissive]
testswitch.cpp:11:8: 錯誤: 跳過了‘int j’的初始化
testswitch.cpp:16:8: 錯誤: 跳轉至 case 標號 [-fpermissive]
testswitch.cpp:11:8: 錯誤: 跳過了‘int j’的初始化
大致的意思是,系統不允許我們在case中定義一個變量,原因是我們在一個case中定義的變量,假如在另一個case中被使用就會出現錯誤,因為一般來說switch語句中的case只能被執行一個。
但是我們假如是想要定義一個在case中使用的臨時變量,那該怎么辦呢。當然是有辦法的其實也很簡單就是我們在寫case語句時給每一個case加一個大括號就行了。例如程序假如如下寫就沒有問題:
(c語言中的報錯是:標號只能是語句的一部分,而聲明並非語句。)
#include<iostream>
using namespace std;
int main()
{
int i;
cout<<"please input the value of i ---(0-9)"<<endl;
cin >> i;
switch(i)
{
case 0:
{
int j = 3;
cout << j <<endl;
break;
}
case 4:
case 1:
case 2:
break;
}
return 0;
}
之所以加大括號就是為了明確我們聲明的變量的作用域,就是僅僅在本case之中。
對此問題的分析:
由於switch的幾個case語句在同一個作用域(因為case 語句只是標簽,它們共屬於一個swtich語句塊),所以如果在某個case下面聲明變量的話,其他的case語句也能看到,這樣的話就可能導致錯誤,例如在地一段代碼中的case 1后面還有個case 2的話,且case 2中使用了case 1定義的變量i的話,那么如果運行時n = 2,switch直接跳轉到case2內部,這樣就出現了i沒有初始化的事情了(變量的聲明是在編譯階段,而變量的賦值則是在運行時),如果能夠運行的話,則在case 2中,i的初始值將是一個未知值。所以編譯器直接避免這種事情的發生,就讓其編譯無法通過。而很明顯加上花括號之后,i的作用域就很明確了。
當然這里我們提到的問題,並不是每個編譯器都會存在。我試驗過java之中就不存在這樣的問題,我們可以隨意在case中聲明變量,因為java之中已經明確規定了case中變量的作用域。這可能是c++編譯器設計上的一個小小的不足吧!這里拿出來跟大家分享一下,希望對大家有點用處吧