2015-03-13 84 views
3

給予代碼:需要澄清無符號字符*用C

... 

int x = 123 

... 

unsigned char * xx = (char *) & x; 

... 

我有xx[0] = 123xx[1] = 0xx[2] = 0

有人能解釋這裏發生了什麼?一般來說,我對指針沒有很好的理解,所以越簡單越好。

感謝

+1

int是32位的4個字節或64位的8個字節。 '123'適合最低有效字節。你的'xx [0]'表示那個字節,所以它的值是'123'。 'xx [1]'是下一個有效字節,即'0',依此類推。 – lurker 2015-03-13 17:19:23

+0

@ lurker這樣做很有道理,你能解釋一下爲什麼xx [i]會這麼做嗎? – 123454321 2015-03-13 17:35:45

回答

3

您正在訪問的序列little-endianint的字節(char S)。小端系統中的中的123通常將被存儲爲{123,0,0,0}。如果您的號碼是783 (256 * 3 + 15),它將被存儲爲{15,3,0,0}

0

呀,你在做什麼,你不應該這樣做......

也就是說......結果的一個部分是你在一個小端處理器工作。語句int x = 123;在堆棧上分配4個字節,並用值123初始化它;由於它是小端,因此內存中的內存看起來像123,0,0,0。如果它是大的Endian,它將是0,0,0,123。你的char指針指向存儲x的內存的第一個字節。

+0

將char和cast轉換爲int *是序列化的常用方法。實際上,它甚至沒有違反嚴格的別名規則。 – doron 2015-03-13 17:27:33

+0

不能保證int是4個字節。我已經看過2,4和8了。另外,有些時候這是一種完全可以接受的技術,但要注意的是,它不適合缺乏經驗的程序員,因爲cn很快就會出錯。 – Degustaf 2015-03-13 17:31:43

0
unsigned char * xx = (char *) & x; 

你把x的地址,你告訴編譯器它是一個指向字符[字符串],您分配到XX,這是一個指向字符[字符串。轉換爲(char *)只是讓編譯器感到高興。

現在,如果您打印xx或檢查它,它可以取決於您所看到的機器 - 所謂的小端或大端存儲整數的方式。 X86是小端,並將整數的字節反向存儲。因此,存儲0x00000123將存儲0x23 0x01 0x00 0x00,這是您在檢查位置xx時指向的字符所看到的內容。

1

我會盡力解釋所有的ASCII圖片。

int x = 123; 

這裏,x是表示int類型的位置的符號。類型int在32位機器上使用4個字節的內存,或在64位機器上使用8個字節。這也可以是編譯器依賴的。但是對於這個討論,我們假設32位(4字節)。在x86

內存管理「小端排序」,意思是如果一個數需要多個字節(它的值是> 255無符號,或者> 127簽署的,單一字節的值),則該號被存儲與至少顯著字節在最低地址。如果您的號碼是十六進制,0x12345678,那麼它會被存儲爲:

​​

您的電話號碼,小數123,是7B十六進制或0000007B(所有4個字節),所以看起來像:

x: 7B  <-- address that `x` represents 
    00  <-- x addr + 1 byte 
    00  <-- x addr + 2 bytes 
    00  <-- x addr + 3 bytes 

爲了使這個更清晰,讓我們編寫一個x的內存地址,比如0x00001000。然後,字節位置將有以下的值:

Address Value 
x: 00001000 7B 
    00001001 00 
    00001002 00 
    00001003 00 

現在你有:

unsigned char * xx = (char *) & x; 

其中定義的指針無符號字符(8位或1字節的無符號值,範圍0-255),其值是整數x的地址。換言之,位於xx的價值是0x00001000

xx: 00 
    10 
    00 
    00 

與號(&)表明您希望地址x。而且,從技術上講,聲明是不正確的。所以,現在你有一個指針,或地址,存儲在變量xx

unsigned char * xx = (unsigned char *) & x; 

:這真的應適當鑄成。該地址指向x

Address Value 
x: 00001000 7B  <-- xx points HERE (xx has the value 0x00001000) 
    00001001 00 
    00001002 00 
    00001003 00 

xx[0]的值是什麼xx0字節偏移。它被字節所抵消,因爲xx的類型是指向一個字節的unsigned char的指針。因此,來自xx的每個偏移計數都是該類型的大小。內存中的值xx[1]只是一個字節,值爲00。等等。插圖:

Address Value 
x: 00001000 7B  <-- xx[0], or the value at `xx` + 0 
    00001001 00  <-- xx[1], or the value at `xx` + 1 
    00001002 00  <-- xx[2], or the value at `xx` + 2 
    00001003 00  <-- xx[3], or the value at `xx` + 3