2011-04-23 67 views
4

我碰到這個代碼案例標籤問題/ C++

#include<stdio.h> 
    int main() 
    { 
     int a=1; 
     switch(a) 
     { int b=20; 
      case 1: printf("b is %d\n",b); 
        break; 
      default:printf("b is %d\n",b); 
        break; 
     } 
     return 0; 
    } 

來到我所期望的輸出爲20,但有一些垃圾值。 將此代碼編譯爲.c文件和.cpp文件時,輸出是否會有所不同?

回答

4

這是一個編程難題或令人髮指的錯誤。

switch的作用類似計算goto。所以它可以是goto 1;goto default;。無論哪種情況,它跳過b = 20;並打印未初始化的垃圾值!

C++編譯器應該通過拒絕編譯來改善這種情況。

8

在C++中,代碼格式不正確,因爲跳轉到case 1會跨越b的初始化。你不能那樣做。

在C中,代碼調用UB是因爲使用了未初始化的變量b

C99 [6.4.2/7]也顯示了一個類似的例子。

實施例在ARTI音響官方程序片段

switch (expr) 
{ 
    int i = 4; 
    f(i); 
    case 0: 
    i = 17; 
    /* falls through into defaultcode */ 
    default: 
    printf("%d\n", i); 
} 

其identi音響ER爲i與自動存儲持續時間的情況下(在塊內),但從來沒有初始化,並且對象因此如果控制表達式具有非零值,對printf函數的調用將訪問一個不確定的值。同樣,無法到達功能f的呼叫。

1

執行流程從來沒有達到int b=20;,所以你得到b的未初始化值(由於編譯器如何分配堆棧變量,它仍然在堆棧上分配)。

的分配要達到它必須在一個case語句或外部和交換機(我很驚訝,編譯器沒有吐出約可達代碼的警告......)以上。

0

不,int b = 20聲明並未實際執行,因爲您跳過它。

希望你的編譯器警告這一點,雖然。

0

如果您使用的是「gcc」Linux編譯器,請使用-Wall選項進行編譯以檢查該編譯器。大綱內的任何內容,除了「case語句」之外都不會理想地執行。但是它如何在C/C++中起作用,你的答案很大程度上取決於你正在使用的編譯器的類型。堅果再次,因爲我上面告訴,int b=20永遠不應該達到,因此,當你打印它的垃圾值的結果。

還有一兩件事,在這種情況下,它是好的,如果你還讓我們知道您正在使用,以獲得更準確的答案編譯器的類型和版本。