我想说明一个枚举,它是另一个typdef枚举的扩展。
一个typedef枚举有4个元素(因为我在结构中只有2个位用于存储其值),另一个具有相同的4个元素,加上第5个元素(未存储在结构中,仅用于标记无效值。)
示例代码:
typedef enum {
case0,
case1,
case2,
case3,
} case_t;
typedef enum {
one_t, // 0 through 3 <---HOW CAN I DO THIS?
invalid_case, // 4
} case_ext_t
struct {
case_t case_ :2; // 2 bits, for up to 4 cases
unsigned other_stuff:14; //
} a_word;
case_ext_t my_case = invalid_case;
if (condition) {
my_case = case2;
}
if (my_case != invalid_case) {
switch (my_case) {
case case0: {....} break;
case case1: {....} break;
case case2: {....} break;
case case3: {....} break;
}
}
我可以输入一个case_ext_t,其中包含case_t的所有元素以及其他元素吗?
或者,我可以定义更大的typedef enum case_ext_t,但在存储2位结构时只使用前4个元素吗?
答案 0 :(得分:2)
我可以输入一个case_ext_t,其中包含case_t的所有元素以及其他元素吗?
不,你不能。如果在给定的翻译单元中将标识符声明为枚举常量,则该标识符必须是翻译单元中该标识符的唯一声明(C2011,6.7 / 5)。因此,如果在同一个翻译单元中使用了两个枚举类型,除了不完整的类型,那么它们就不能有任何共同的枚举常量。
或者,我可以定义更大的typedef enum case_ext_t,但在存储2位结构时只使用前4个元素吗?
没有。位域声明可能不会指定比字段的基本类型实际具有的更多位(C2011,6.7.2.1/4)。此外,它是实现定义的,您是否可以使用枚举类型作为位字段&#39;无论指定的位数如何,都要声明类型;唯一可以保证允许的类型是_Bool
,signed int
和unsigned int
(C2011,6.7.2.1 / 5)。
我认为您最好的选择是将您的位域声明为类型unsigned int
,并且只声明更大的枚举类型:
typedef enum {
case0,
case1,
case2,
case3,
invalid_case, // 4
} case_t;
struct {
unsigned case_:2;
unsigned other_stuff:14;
} a_word;
对invalid_case
使用适当的测试来保护a_word.case_
的作业。
或者,你真的需要使用位域吗?这似乎引起了很多人的惊愕,并且根本不清楚这个问题是否值得。为什么不简单地使用
struct {
case_t case_;
unsigned other_stuff;
} a_word;
答案 1 :(得分:1)
您不能使用另一个值扩展枚举。
但你可以使用一点宏技巧来做你想做的事情:
#include <stdio.h>
#define base_enum(prefix) prefix##case0,prefix##case1,prefix##case2,prefix##case3
typedef enum {
base_enum()
} case_t;
typedef enum {
base_enum(ext_),
invalid_case, // 4
} case_ext_t;
int main()
{
printf("Base %d, ext %d, %d\n",case1,ext_case1,invalid_case);
return 0;
}
因此,您使用前缀在宏中定义基本枚举。
然后在声明case_t
时使用不带前缀的宏,并在声明&#34;扩展&#34;时使用另一个前缀枚举。您可以在宏之后添加其他枚举。
我的示例打印:Base 1, ext 1, 4