2015-05-26 30 views
0

我試過下面的c程序&我希望得到編譯時錯誤,但爲什麼編譯器沒有給出任何錯誤?爲什麼編譯器在傳遞int(不是int *)作爲scanf()的參數時不會發出錯誤?

#include <stdio.h> 
#include <conio.h> 
int main() 
{ 
    int a,b; 
    printf("Enter a : "); 
    scanf("%d",&a); 
    printf("Enter b : "); 
    scanf("%d",b); 
    printf("a is %d and b is %d\n",a,b); 
    getch(); 
    return 0; 
} 

我不寫&scanf("%d",b)。在編譯時,編譯器不會給出任何錯誤,但在執行期間,b的值是2686792(垃圾值)。

+1

您是否使用'-Wall'或任何特定警告進行編譯? – Eregrith

+4

爲什麼不能編譯? 'scanf'和'printf'家族是接收未知類型的可變函數,因此編譯器無法檢查參數的類型是否正確。它們的所有參數遵循默認升級 –

+2

編譯時沒有理由失敗。 – juanchopanza

回答

2

作爲每C11標準,第§6.3.2.3

的整數可以被轉換爲任何指針類型。除前面指定外, 結果是實現定義的,可能未正確對齊,可能不指向引用類型的實體,可能是陷阱表示。

所以,編譯器將允許這個,但結果是實現定義的。

在這種特殊情況下,你傳遞給b作爲scanf()的說法,這是未初始化,這將導致程序來調用undefined behaviour,執行一次。

此外,printf()/scanf()是可變參數的功能,上paramater 類型沒有檢查一般是perforfmed,除非通過編譯器標誌明確要求[見-Wformat]。

1

這不是編譯時錯誤,而是運行時問題。

編譯器希望你已經給出了一個有效的地址來掃描該值,在運行時只有它會知道地址是否有效。

如果您嘗試將該值掃描到無效地址,則會導致未定義的行爲並可能看到崩潰。

1

它掃描得很好,因爲scanf需要在其參數中存儲位置。這就是爲什麼我們使用&來給出相應變量的內存位置。

在你的情況scanf只是掃描輸入的值,並把它放在其中有b值的存儲位置(而不是掃描,並把它在b存儲在存儲器中的位置)。

0

C中的&運算符返回操作數的地址。如果只給出沒有&運算符的b,則它將按值傳遞,並且scanf將無法​​設置該值。這會導致意外的行爲,因爲你已經注意到了。它無法在運行時驗證地址,因此直到運行時纔會注意到問題。

相關問題