[英]Create Nested If and else Define C Programming
我需要一些幫助。 我想為位操作創建一個#define。 另外,對於位操作本身,我想檢查大小以確保我正在執行具有相同數據類型大小的位操作。
所以我在這里嘗試的是:
#define bitset(byte,nbit) (sizeof(nbit) <= 2 ? (sizeof(nbit) == 2 ? ((byte) |= ((uint16)1<<(nbit))) : ( (byte) |= ((uint8)1<<(nbit)))) \
: (sizeof(nbit) == 8 ? ((byte) |= ((uint64)1<<(nbit))) : ( (byte) |= ((uint32)1<<(nbit)))\
我做了什么嗎? 錯誤的? 甚至可以創建這樣的定義嗎?
這個定義正確嗎?
不,你犯了一些錯誤。
首先,我相信你想檢查sizeof(byte)
而不是代表位數的變量的大小......
應該是== 8? ((byte) |= ((uint64)1<<(nbit))
== 8? ((byte) |= ((uint64)1<<(nbit))
,因此當byte
有8
個字節時選擇uint64_t
。
您在定義末尾錯過了\
以將其與下一行連接起來。
您最后錯過了兩個))
以關閉打開的。
沒有uint8
和uint64
等。 stdint.h
中有uint16_t
和uint8_t
等類型。 使用標准類型。
但是請考慮更清晰的格式:
#define bitset(byte,nbit) ( \
sizeof(byte) == 1 ? ((byte) |= (uint8_t)1<<(nbit)) : \
sizeof(byte) == 2 ? ((byte) |= (uint16_t)1<<(nbit)) : \
sizeof(byte) == 4 ? ((byte) |= (uint32_t)1<<(nbit)) : \
((byte) |= (uint64_t)1<<(nbit)) \
)
甚至可以創建這樣的定義嗎?
是的。 如果您不關心返回值並且表達式不必是常量表達式,那么您甚至可以使用舊的do {... } while(0)
技巧(實際上是約定)編寫完整的語句:
#define bitset(byte,nbit) do { \
static_assert(sizeof(byte) == 1 || \
sizeof(byte) == 2 || \
sizeof(byte) == 4 || \
sizeof(byte) == 8, \
"nbit has wrong size"); \
assert(nbit < sizeof(byte) * CHAR_BIT); /* right? */ \
switch (sizeof(byte)) { \
case 1: (byte) |= (uint8_t)1<<(nbit); break; \
case 2: (byte) |= (uint16_t)1<<(nbit); break; \
case 4: (byte) |= (uint32_t)1<<(nbit); break; \
case 8: (byte) |= (uint64_t)1<<(nbit); break; \
} \
} while(0)
或類似的。 您還可以探索_Generic
並使您的代碼僅明確接受您想要的這些類型:
void bitset_8(uint8_t *byte, unsigned nbit) {
*byte |= (uint8_t)1<<nbit;
}
void bitset_16(uint16_t *byte, unsigned nbit) {
*byte |= (uint16_t)1<<nbit;
}
void bitset_32(uint32_t *byte, unsigned nbit) {
*byte |= (uint32_t)1<<nbit;
}
void bitset_64(uint64_t *byte, unsigned nbit) {
*byte |= (uint64_t)1<<nbit;
}
#define bitset(byte,nbit) (_Generic((byte), \
uint8_t: bitset_8, \
uint16_t: bitset_16, \
uint32_t: bitset_32, \
uint64_t: bitset_64)(&byte, nbit))
總而言之,這個function只是一個例子。 在實際代碼中,我無論如何都會寫:
#define bitset(byte,nbit) ((byte) |= 1ull<<(nbyte))
因為我相信編譯器會足夠聰明地內聯表達式並且編譯器會優化,如果byte
具有例如 8 位,那么就不需要使用完整的 64 位算術,它將使用 8 個字節。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.