[英]Create Nested If and else Define C Programming
i need some help.我需要一些帮助。 i want to create a #define for an bit operation.
我想为位操作创建一个#define。 Additional, to the bit operation itself i want to check the sizes to be sure that i am performing a bit operation with the same data type size.
另外,对于位操作本身,我想检查大小以确保我正在执行具有相同数据类型大小的位操作。
So what i tried is this here:所以我在这里尝试的是:
#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)))\
Did i made sth.我做了什么吗? wrong?
错误的? Is it even possible to create such a define?
甚至可以创建这样的定义吗?
Is this define correct?
这个定义正确吗?
No, you made some mistakes.不,你犯了一些错误。
Firstly, I believe you want to check sizeof(byte)
not the size of the variable that represents the bit number...首先,我相信你想检查
sizeof(byte)
而不是代表位数的变量的大小......
It should be == 8? ((byte) |= ((uint64)1<<(nbit))
应该是
== 8? ((byte) |= ((uint64)1<<(nbit))
== 8? ((byte) |= ((uint64)1<<(nbit))
, so that uint64_t
is picked when byte
has 8
bytes. == 8? ((byte) |= ((uint64)1<<(nbit))
,因此当byte
有8
个字节时选择uint64_t
。
You missed a \
on the end of define to join it with the next line.您在定义末尾错过了
\
以将其与下一行连接起来。
You missed two ))
on the end to close the open ones.您最后错过了两个
))
以关闭打开的。
There are no uint8
and no uint64
etc. There are types uint16_t
and uint8_t
etc. from stdint.h
.没有
uint8
和uint64
等。 stdint.h
中有uint16_t
和uint8_t
等类型。 Use standard types.使用标准类型。
But consider however a clearer formatting:但是请考虑更清晰的格式:
#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)) \
)
Is it even possible to create such a define?
甚至可以创建这样的定义吗?
Sure it is.是的。 If you do not care about the return value and the expression doesn't have to be a constant expression, then you could even write full statements with the old
do {... } while(0)
trick (or convention actually):如果您不关心返回值并且表达式不必是常量表达式,那么您甚至可以使用旧的
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)
or similar.或类似的。 You may also explore
_Generic
and make your code accept explicitly only these types that you want to:您还可以探索
_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))
All in all, this function is just an example.总而言之,这个function只是一个例子。 In real code I would anyway write:
在实际代码中,我无论如何都会写:
#define bitset(byte,nbit) ((byte) |= 1ull<<(nbyte))
as I trust the compiler will be smart enough to inline the expression and compiler will optimize, that if byte
has for example 8 bits, then there's no need to use full 64-bit arithmetic and it will use 8 bytes.因为我相信编译器会足够聪明地内联表达式并且编译器会优化,如果
byte
具有例如 8 位,那么就不需要使用完整的 64 位算术,它将使用 8 个字节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.