简体   繁体   English

创建嵌套 If 和 else 定义 C 编程

[英]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)) ,因此当byte8个字节时选择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 .没有uint8uint64等。 stdint.h中有uint16_tuint8_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM