如果我有4個位元組的記憶體,并希望以無符號長條L和字符c[4]的形式訪問該記憶體。在 C 語言中,最有效的方法是什么?
例如,如果我將L設定為300,那么位元組將被設定為0x0000012c,如果我訪問c[3],我將期望看到0x2c
。如果我將c[3]增加1,它就變成了0x2d,L現在的值是301
。謝謝你
uj5u.com熱心網友回復:
你可以創建一個兩種型別的union:
union u1 {
unsigned long l;
char c[sizeof(unsigned long) ] 。
};
這樣,如果你創建了一個聯合型別的變數,你就可以向一個成員寫入,并讀取另一個。
但是請記住,其結果取決于您的系統的endianness。 大多數基于 x86 的系統都是小位元組(little-endian),這意味著最小有效位元組在前。 如果是這種情況,c[0]成員的值實際上是2c。
uj5u.com熱心網友回復:
你可以使用union和type punning來調查記憶體:
#include <stdint.h>/span>
#include <stdio.h>
typedef union {
uint32_t L。
char c[sizeof(uint32_t)] 。
} foo;
int main() {
foo x;
x.L = 123;
printf("%X %X %X %X
", x.c[0], x.c[1], x.c[2], x.c[3] )。)
}
輸出可能是7B 0 0或0 0 0 7B,這取決于你的機器的編碼方式。
uj5u.com熱心網友回復:
如果你有被定義為unsigned long的記憶體,如unsigned long L;,那么你可以通過一個char值來訪問它的位元組,如:
char *c = (char *) & L;
printf("L的位元組3是%d。
", c[3] )。)
這樣做是因為C 2018 6.3.2.3 7說:
...當一個指向物件的指標被轉換為指向字符型別的指標時,結果指向物件的最低尋址位元組。結果的連續增量,直到物件的大小,產生指向該物件剩余位元組的指標。
而6.5 7說我們可以通過一個字符型別來訪問任何物件:
一個物件只能通過具有以下型別之一的lvalue運算式來訪問其存盤的值:
-----與下列型別兼容的型別
- 一種與物件的有效型別兼容的型別,
- 一種與物件的有效型別兼容的型別。
...
- 一種字符型別。
對于一個通過在分配的記憶體中存盤一個無符號長而創建的無符號長來說也是如此,就像無符號長*p = malloc(sizeof *p); *p = 300;。
然而,unsigned long中的位元組的順序是由實作定義的。C 要求無符號整數型別使用純二進制符號,但并沒有指定位元組內的位元順序或表示內的位元組順序,而且它還允許填充。
此外,一般來說,使用無符號的char來訪問位元組,而不是char,以避免潛在的有符號性的復雜問題。
如果你只有 "一些記憶體",比如在一個嵌入式系統中的一個特殊區域,并且你希望像上面描述的那樣既能以無符號長字串又能以字符來訪問它,那么你可能需要你的編譯器提供超出C標準的支持。當然,打算在嵌入式系統中使用的 C 實作通常會根據需要提供對此類記憶體的訪問支持。
然而,即使您沒有定義或分配的物件,并且沒有來自編譯器的特殊支持,您也可以通過使用字符型別將unsigned long的位元組放入該記憶體。特別是,memcpy被定義為逐個位元組的復制,所以它將為:
unsigned long L = 300; //準備一個正常的無符號long。
memcpy(target, L, sizeof L); //將L的位元組復制到指標 "target "的地址。
然后,當然,你也可以設定一個字符指標指向與target相同的地方,并使用該指標來訪問位元組,如上所述。
另一種為兩個或多個物件型別使用相同記憶體的方法是通過一個聯盟。這在C語言中被定義了,但在C 中沒有:
typedef union
{[/span>
unsigned long L。
char c[4] 。
} 我的聯盟。
MyUnion x = { .L = 300 };
printf("無符號長的位元組3是%d。
", x.c[3] )。)
這樣做的原因是C 2018 6.5.2.3 3告訴我們,.運算子訪問聯盟中命名的成員的值,并且注釋99明確指出,如果請求的成員不是最后存盤的,"值的物件表示的適當部分被重新解釋為新型別中的物件表示"。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/329581.html
標籤:
上一篇:有沒有辦法用reactmaterialUI創建一個如下圖所示的組件?
下一篇:Ccalloc和vla
