2014-08-30 42 views
0
int main() 
{ 
    int i=21; 
    char *p; 
    p=(char*)&i; 

    printf("%d",*p); 

    getch(); 
    return 0; 
} 

printf聲明給了我完美的答案,但我認爲它不應該有作爲'p'是一個字符指針,將能夠挽救它的基地址,但int佔用兩個空格,*p不該不能給我整數值,因爲它會指向地址,比如說X,但int存儲在兩個字節中,所以值需要從XX+1地址收集,但我運行此代碼並給了我值,或者我對此有錯誤的看法?取整數值

+0

是的,你有。谷歌「排序」和「符號擴展」。 – 2014-08-30 05:37:43

+2

21位於字符或1個字節的範圍內。將i增加到256以上。 – 2014-08-30 05:42:04

+0

您使用'%d',但您說它不應該打印整數值。 – 2014-08-30 05:43:09

回答

3
p=(char*)&i; 

這點pi最低的地址。無論是低位字節還是高位字節的地址,都取決於系統的字節順序。 (它甚至可以是一個內部字節...... PDP-11是小端的,但是長的(32位)首先存儲在高位的16位字中,所以字節順序是2,3,0,1。)可能你運行在一個小端機(x86's)上,所以它指向低位字節。

*p 

鑑於小字節序,這取的i低位字節,它是(炭)21,然後執行預設轉換爲int,得到(INT)21,以及打印21.如果i包含一個> 255的值,你會得到「錯誤」的結果。此外,如果它包含值> 127和< 256並且字符在您的系統上被簽名 - 它會打印一個負值。

由於結果取決於機器的字節順序,並且由實現定義,因此不可移植,所以除非您的具體目標是確定機器的字節順序,否則不應該這樣做。開始的程序員應該花更少的時間來試圖理解壞代碼爲什麼有時「起作用」,而是學習如何編寫好的代碼。一般規則(有很多例外):帶有強制轉換的代碼是錯誤的代碼。

+0

在這裏,行爲是**不**未定義,只有實現定義。 – 2014-08-30 06:11:38

+1

@TheParamagneticCroissant啊,你是對的;我相應地編輯了我的答案。該標準允許將指向任何對象的指針轉換爲char *,該指針產生對象的最低地址,並允許對其進行解引用,甚至遍歷該對象,並且第6.2.6.1節說:「除了位域,對象由一個或多個字節的連續序列組成,其數量,順序和編碼明確指定,或者由實現定義「 」。 – 2014-08-30 08:37:49

+0

@MattMcNabb「某些對象表示形式不需要表示對象類型的值。如果對象的存儲的 值具有這樣的表示並且被左值表達式**讀取,而 不具有字符類型**,則行爲是未定義的。「該標準保證能夠處理任何對象時間。 – 2014-08-30 09:30:44