[英]Dereferencing and typecasting
我構建了以下代碼部分,以幫助自己理解C語言中的指針解引用和類型轉換。
char a = 'a';
char * b = &a;
int i = (int) *b;
對於以上內容,我了解到,在第三行,我已取消引用b並得到了'a',並且(int)會將'a'的值轉換為對應的值97,並將其存儲到i中。 但是對於這段代碼:
char a = 'a';
char * b = &a;
int i = *(int *)b;
這導致我是一些任意大數,例如792351。我假設這是一個內存地址,但是我的問題是為什么? 當我將b輸入類型轉換為整數指針時,這是否實際上導致b指向內存中的其他區域? 到底是怎么回事?
編輯 :如果上述方法不起作用,那么為什么這樣的事情會起作用:
char a = 'a';
void * b = &a;
char c = *(char *)b;
這正確地將“ a”分配給c。
您的int
大於char
您在內存中得到一個'a'
值+一些隨機數據。
例如,假設此布局在內存中:
'a'
0xFF
0xFF
0xFF
您的char *
和int *
都指向'a'
。 取消引用char *
,僅獲得第一個字節'a'
。 當您取消引用int *
(假設您的int是32位)時,將得到'a'
和緊隨其后的3個字節的未初始化數據 。
編輯:響應更新的問題:
在char c = *(char *)b;
,b仍指向'a'
值。 您將其轉換為char *
,然后取消引用,得到char *
指向的char *
您關心的最后一行是一件非常糟糕的事情。 首先,它將b視為int*
而b是char*
。 即,由b指向的內存指針被假定為4個字節(通常)而不是1個字節。 因此,當您取消引用它時,它會到達實際b所指向的1個字節,也占用以下3個字節,將這4個字節視為單個int,然后為您提供結果。 這就是為什么它是垃圾。
通常,必須非常謹慎地將一種指針類型轉換為另一種指針類型。
您正在將char
指針轉換為int指針。 字符(通常)存儲為8位。 另一方面, int
是32位(在64位系統上為64位)。 因此,如果您查看8位b
旁邊的其他24位內存,則會得到一堆未初始化的額外位。 即使*b
在i
的位置也取決於體系結構。
big-endian: **** ****|**** ****|**** ****|0110 0001
little-endian: 0110 0001|**** ****|**** ****|**** ****
當您轉換存儲在上面的字符時,所有星號都將變為相關。
由於char
長度為1個字節,而int
4,所以當您從單個字符的地址讀取int
時,您將讀取該字符和另外3個字節。 這些字節的內容就是發生在內存中的所有內容(指針, b
的值),甚至可能未被分配(導致分段錯誤 )。
當您將類型轉換為(int *)類型時,它將在內存中引用總共4個字節(如果為int ,則為size)。
在第二種情況下,您將相同的地址當作指向int的地址。 正式地,結果就是簡單的不確定行為。
實際上,發生的情況是,從該地址開始的四個1字節中的任何內容都被解釋為一個int。
1 4個字節,假定為32位int -如果您的實現具有例如64位int,則為8個字節。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.