簡體   English   中英

我無法理解這種類型的鑄造

[英]I can't understand this type casting

我用intchar進行了類型轉換但沒有使用指針進行類型轉換所以我發布了這個問題。

#include <stdio.h>
int main() {
    int a[4] = { 1, 2, 6, 4 };
    char *p;
    p = (char *)a;   // what does this statement mean?
    printf("%d\n",*p);
    p = p + 1;        
    printf("%d",*p);  // after incrementing it gives 0 why?
}

第一次調用printf給出了數組的第一個元素。 p=p+1它給出0 為什么?

讓我們設想一個相當典型的平台,其中一個字節是8位,內存使用little-endian字節排序排列, int表示內存中的4個字節。 在這個平台上,值為1將如下布局:

00000001 00000000 00000000 00000000
^
the first element of 'a'

p被聲明為char (不是int )的指針,並被初始化為指向數組a的第一個元素。 此平台上的char表示一個字節。 上面解釋為charint值看起來像這樣:

00000001 -------- -------- --------
|      |
 ------
 char is only 8 bits wide

因此,無論我們讀取一個字節還是四個字節,即我們是否讀取*pa[0] ,該值為1 但是,當你遞增p ,一個指向char的指針時,它現在指向內存中的下一個char ,這是下一個字節:

00000001 00000000 00000000 00000000
00000001 00000000 -------- --------
^        ^        ^        ^
p       p+1      p+2      p+3       ...

a[1]指向下一個int2 ), p[1]指向下一個char ,即0


另外,您實際上偶然發現了一種確定給定處理器是使用小端還是大端字節順序的方法。 如果系統是big-endian(最重要的字節優先),那么你的第一個printf將打印0.這是因為內存布局會發生變化:

0000000 00000000 00000000 00000001
^
the first element of 'a'

0000000 -------- -------- --------
^
p

如果您有多個以big-endian順序排列的字節,表示值1,並且您只讀取第一個字節,則可以使用其值( 10 )來測試機器的字節順序:

int n = 1;
if(*(char*)&n == 1)
    // little endian
else
    // big endian

確切地說,第一個printf沒有給出數組的第一個元素,它給出了第一個元素的前8位 ,它恰好等於第一個元素的數值。 第二個printf給出第一個元素的下一個8位,在這種情況下為0。

1 = 00000000 00000000 00000000 00000001(32位)

你有一個由四個整數組成的數組。 您嘗試將它們作為字符的“數組”進行訪問。 這就是鑄造意味着什么。

至於第二個printf打印零,請記住整數是四個字節,而字符只有一個。 因此,增加指針p將使p指向第一個整數的第二個字節,即零。 如果你有一個更大的數字(即超過255),那么第二個字節也會有一個值。 但需要注意的是,這只適用於大端機器上的英特爾型機器,它們都是小端機器,而printf打印機都是零。

int a[4] = { 1, 2, 6, 4 };

聲明一個as數組。 a此時存儲數組的第一個元素的地址。

char *p;

將p聲明為pointer characterpointer

p = (char *)a;

現在,因為pa都存儲了地址。 所以存儲在該地址aaddress陣列的第一個元素的)被分配給p 類型轉換完成,因為p被聲明為char *

它的作用是,假設存儲在a地址為100, 並假設int占用2個字節而char占用1個字節的內存

a+1 would return a+size of int(2) = 102

p+1 would return p+size of char(1) = 101 

這將解釋輸出為

A.存儲在aa兩個字節包含數組的第一個元素。

B.存儲在p的一個字節是整數1的第一個字節的字符表示,即0

希望這可以幫助。

如果使用類似處理器的英特爾,則使用小端格式存儲堆棧上的字節。 更重要的是,類型int(在您的計算機上)可能有4個字節大小而char是1個字節長(您可以使用c運算符'sizeof'來驗證這一點),因此整數數組的第一個元素是:

0x04 0x00 0x00 0x00

因此,當您使用char指針查看整數數組的值時,您會在時間(而非4)前進一個字節,並獲得您獲得的明顯結果。

我希望這有幫助!

a是指向內存數組的指針。 該存儲器可能以小端二進制補碼格式排列為16字節的連續塊。

當你施放它時,你基本上只是說“好吧,我知道這是一個指向一組int的指針,但現在我們將把數據重新解釋為一個字符數組”。 char通常是一個字節。 因此,當您向指針添加一個時,會增加指針指向的位置 因為它是一個char數組,所以它向下推進了數組的一個字節 ,該數組位於int的中間,其中包含0。

根據我對您計算機架構的假設 ,澄清一下

小端數(最低有效字節首先出現):
0000000100000000000000000000000000二進制= 1十進制000000100000000000000000000000000二進制= 2十進制00000110000000000000000000000000二進制= 6十進制00000100000000000000000000000000二進制= 4十進制

你的int數組看起來像這樣:

00000001000000000000000000000000000000100000000000000000000000000000011000000000000000000000000000000100000000000000000000000000

變量“a”指向第一個整數,即32位(即“* a”是00000001000000000000000000000000 )。 如果向變量“a”添加一個,則遞增指針 ,因此*(a + 1)指向第二個int 00000010000000000000000000000000 )。

現在,將變量“a”轉換為“char *”指針。 所以,現在,變量“p”指向同一個地方,但因為它是一個char指針,指向第一個char的指針,即8位(即“* p”是00000001 ,數組的第一個字節) 。

最后,當你增加“p”時,你增加指針 因為“p”是指向字符的指針,所以它前進一個字節 ,因此“*(p + 1)”是00000000

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM