說我有一個更大的型別。
uint32_t big = 0x01234567;
那么我能做些什么呢(char*)&big,在轉換后將指標解釋為 char 型別?
- 那是一個未定義的行為轉變的地址
(char*)&big來(char*&big) 1,(char*&big) 2等? - 這是shift和edit 的未定義行為
(char*)&big 1嗎?就像下面的例子。我認為這個例子應該是一個未定義的行為,因為在轉換為之后(char*),我們將視線限制在一個char- 型別的指標上,我們不應該訪問,甚至改變這個范圍之外的值。
uint32_t big = 0x01234567;
*((char*)&big 1) = 0xff;
printf("x\n\n\n", *((char*)&big 1));
printf("x\n\n\n", big);
(這通過了我的 Visual C 編譯器。順便說一句,我想問一個分叉的問題,為什么在這個例子中第一個printf給出了ffffffff?不應該是ff嗎?)
- 我見過這樣的代碼。這就是我在需要完成類似任務時通常會做的事情。這是UB嗎?為什么或者為什么不?實作這一目標的標準方法是什么?
uint8_t catcher[8] = { 0 };
uint64_t big = 0x1234567812345678;
memcpy(catcher, (uint8_t*)&big, sizeof(uint64_t));
uj5u.com熱心網友回復:
那么我能做些什么呢
(char*)&big,在轉換后將指標解釋為 char 型別?
如果 achar是八位,這在大多數現代 C 實作中都是這樣,那么 中有四個位元組uint32_t big,您可以對從(char *) &big 0到的地址進行算術運算(char *) &big 4。您還可以從(char *) &big 0to讀取和寫入位元組(char *) &big 3,這些位元組將訪問big. 盡管算術被定義為最多作業(char *) &big 4,但這只是一個端點。那里沒有定義的位元組,您不應該使用該地址來讀取或寫入任何內容。
- 那是一個未定義的行為轉變的地址
(char*)&big來(char*&big) 1,(char*&big) 2等?
這些是加法,而不是移位,語法是(char *) &big 1,不是(char*&big) 1。算術是為從 0 到 4 的偏移量定義的。
- 這是shift和edit 的未定義行為
(char*)&big 1嗎?
允許big使用指向 的指標讀取和寫入位元組char。這是字符型別的特殊規則。通常,不應使用不相關的型別訪問物件的位元組。例如,float無法使用int型別訪問物件。但是,字符型別是特殊的;您可以使用字符型別訪問任何物件的位元組。
但是,最好為此使用unsigned char它,因為它避免了帶符號值的復雜性。
- 我見過這樣的代碼。
允許使用 讀取或寫入物件的位元組memcpy。memcpy被定義為就像通過復制字符一樣作業。
請注意,雖然訪問物件的位元組是由 C 標準定義的,但位元組如何表示值部分是由實作定義的。不同的 C 實作可能對物件內的位元組使用不同的順序,并且可能存在其他差異。
順便說一句,我想問一個分叉的問題,為什么在這個例子中第一個
printf給出ffffffff?不應該ff嗎?
在您的 C 實作中,char是有符號的,可以表示從 -128 到 127 的值。在*((char*)&big 1) = 0xff;,0xff是 255 并且太大而無法放入char. 它char以實作定義的方式轉換為值。您的 C 實作將其轉換為 -1。(-1 的八位二進制補碼表示,位 11111111,使用與 255 的二進制表示相同的位,同樣是位 11111111。)
然后printf("x\n\n\n", *((char*)&big 1));將此值 -1 傳遞給printf。既然是char,就提升int為要傳遞給printf。這產生相同的值 -1,但它有 32 位,111111111111111111111111111111111。然后你傳遞了一個int,但printf期望一個unsigned intfor x。這種行為不是由 C 標準定義的,但您的 C 實作讀取 32 位,就好像它們是unsigned int. 作為unsigned int,32 位 11111111111111111111111111111111 表示值 4,294,967,295 或0xffffffff,所以這就是printf列印的內容。
您可以使用 列印正確的值printf("hhx\n\n\n", * ((unsigned char *) &big 1));。作為unsigned char,位 11111111 表示 255 or 0xff,并將其轉換為int255 or 0x000000ff。
uj5u.com熱心網友回復:
對于可變引數函式(如printf),所有引數都會進行默認引數提升,從而將較小的整數型別提升為int。
如果較小的型別是有符號的,則此轉換將包括符號擴展,因此該值保持其值。
因此,如果char是具有值的有符號型別(由實作定義),-1那么它將被提升為int值-1。這就是你所看到的。
如果要列印較小的型別,您首先需要轉換為正確的型別 ( unsigned char),然后使用正確的格式(例如%hhx列印unsigned char值)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/314982.html
上一篇:如何將陣列分配給指標?
下一篇:二維陣列指向什么?
