2011-12-23 54 views
3
short int a,b,c; 
scanf("%d%d",&a,&b); 
c = a + b; 
printf("%d %d %d",a,b,c); 

輸入:5 8短而在C INT

輸出:0 8 8

爲什麼是a 0的值?任何人都可以解釋這個嗎?

平臺--- GCC的Ubuntu 10.04

回答

11

scanf"%d"格式需要一個int*參數。你給它一個short int*參數,因此你的程序的行爲是未定義的。

如果你真的想知道爲什麼你得到你得到的結果,我就可以在猜測,但它更容易只是爲了糾正代碼:

scanf("%hd%hd", &a, &b); 

您可以繼續使用"%d"printf,因爲short int參數被提升爲int。您可以使用"%hd"printf,但這不是必需的。 (有沒有類似推廣short int*參數int*。)


您可以安全地停止閱讀這裏。


以下是關於您的錯誤代碼中可能發生的情況的一些猜測。這不是一個解決方案;解決方案是糾正你的代碼,以便它做你想做的事情。但是,看看錯誤代碼的不正確性可能會很有啓發性。

假設short是16位,並且int是32位,這是典型的。格式字符串中的第一個"%d"告訴scanf讀取一個值(您給它的值爲5)並將其存儲到由第二個參數&a指向的32位int中。由於a只有16個buts,所以它將在a中存儲一半的32位值,另一半存儲在相鄰的某塊存儲器中。第二個"%d"&b做同樣的事情;它將8的32位表示的一半存儲在b中,另一半存儲在其他地方。

根據你的輸出,看來第二"%d"引起scanf到低位存儲在b8的16位,高位的16位(具有0值)a,覆蓋值存儲在第一個"%d"。請注意,第一個"%d"的高位16位可能存儲在其他地方,可能會破壞其他一些變量,或者可能寫入其他未使用的內存。

因此,結果是,您在ab中存儲了0,這說明了您獲得的輸出。

所有這些都是非常推測的,許多其他的結果都是可能的。這種分析是有用的只有跟蹤不正確的代碼的行爲,其目的是糾正它。編寫故意利用這種事情的代碼是一個非常糟糕的主意。該語言絕對沒有說這樣的錯誤代碼會做什麼;它的行爲可以在不同的系統,不同的編譯器設置,甚至取決於月亮的相位上大不相同。

+0

@Arya Keith的炒作是非常可能是對的。打印'a,b,c'的地址,我得到了&a = 0x7fffee2bee8e,&b = 0x7fffee2bee8c,&c = 0x7fffee2bee8a'(gcc-4.5.1,x86_64)。通過這些地址上的變量,在一個小端系統中,這個推測準確地描述瞭如果編譯器不會因爲允許而編造僞造代碼而不知所措。 – 2011-12-23 21:39:41

0

在VC++ 6.0的c值是13

#include <stdio.h> 

int main() 
{ 

short int a,b,c; 
scanf("%d%d",&a,&b); 
c = a + b; 
printf("%d + %d = %d\n",a,b,c); 


return 0; 
} 
+0

行爲未定義; a,b和c的值完全可以是任何東西。 – 2011-12-23 21:37:37