我在 C 编程语言中使用了很多枚举标志。一个非常好的解决方案。但是我现在有一个问题:我需要实现超过 32 个标志选项,因为它的值太大,所以无法保存1 << 32
。enum
那么,我该如何解决这个问题?也许我应该使用#define
而不是enum
和unsigned long int
而不是unsigned int
?这会正常工作吗?a struct
with bitfields对我来说不是一个有效的解决方案,因为它不是 C ANSI标准代码。
您应该在 C中查看static const
vs。#define
听起来好像您正在使用一般形式的枚举:
enum
{
FLAG_A = 0x00000001, FLAG_B = 0x00000002, FLAG_C = 0x00000004, FLAG_D = 0x00000008,
...
};
您还可以通过按位运算将这些不同的枚举值组合成一个(32 位)unsigned int
值。现在你已经达到了极限;你有超过 32 个标志(我相信它们的命名比我的例子中更有意义)。
您可以决定开始一系列新的枚举,使用第二个 32 位(无符号)整数来存储位。这具有将符号保留在可调试程序中的优点(与#define
即使在可调试程序中也很少可用的常量不同)。缺点是您可能需要在之前传递一个值的地方传递两个值。
如果必须将标志保留在单个变量中,则需要检查使用 是否更好unsigned long long
,或者可能使用具有两个unsigned int
值的结构。
我同意最好不要使用位域,尽管它们可能工作得很好。我也会竭尽全力避免使用#define
,并且可能会使用两个 32 位变量或一个结构。很大程度上取决于您的代码库,以及这些值的使用范围。
您可以让您的enum
值遵循顺序值排序,这将允许最多INT_MAX + 1
枚举值。但是,如果少于 64,则可以使用 anunsigned long long
来携带一组值:
unsigned long long set_MyEnum (unsigned long long my_enum_set, enum MyEnum e) {
return my_enum_set | (1U << e);
}
unsigned long long unset_myEnum (unsigned long long my_enum_set, enum MyEnum e) {
return my_enum_set & ~(1U << e);
}
int is_set_MyEnum (unsigned long long my_enum_set, enum MyEnum e) {
return my_enum_set & (1U << e);
}
如果您有 64 个或更多,那么您可以将您的集合定义为某种数组。