- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 C 语言中,常见的做法是...
enum {
A,
B,
C,
};
但是对于标志,您需要明确定义它们......
enum {
A = (1 << 0),
B = (1 << 1),
C = (1 << 2),
};
是否可以定义标志而不必显式列出每个值?
自从发布这个问题以来,对于您为什么要这样做似乎有些困惑。需要明确的是,显式定义标志通常是一件“好事”,所以我的问题是关于一些相当模糊的极端情况,而您可能想避免它。
<小时/>注意:这假设这些标志只是“槽”,它们不会写入磁盘或以持久的方式使用,这会破坏 API 和网络协议(protocol)。等等
这样做的能力可以排除一小类错误......
这样做的好处是添加/删除位,不需要更改 enum
标识符之后的每个值。
诚然,这不是您想要一直使用的功能。但在某些特殊情况下它很有用。
<小时/>注意到现有的(较差的)解决方案,这些解决方案在某种程度上有效,但不满意(这就是我问这个问题的原因)
它可以工作,但与直接定义标志相比并没有显着的优势。
enum {
A_SHIFT,
B_SHIFT,
C_SHIFT,
};
enum {
A = (1 << A_SHIFT),
B = (1 << B_SHIFT),
C = (1 << C_SHIFT),
};
<小时/>
__COUNTER__
主要缺点是它仅适用于 GCC,并依赖于定义一些唯一的起始值来使用枚举...这会污染 namespace 。
#define ENUM_INC (1 << (__COUNTER__ - _FIRST))
enum { _FIRST = __COUNTER__ + 1 };
enum {
A = ENUM_INC,
B = ENUM_INC,
C = ENUM_INC,
};
#undef ENUM_INC
最佳答案
如果您愿意超越纯 C,您可以使用预处理过滤器为您生成一些代码。
例如,这是一个简单的 Perl 脚本:
#!/usr/bin/perl
use strict;
use warnings;
my $flag_bit = 0;
while (<>) {
if (/\@RESET_FLAG\@/) {
s/\@RESET_FLAG\@//;
$flag_bit = 0;
}
elsif (/\@FLAG\@/) {
s/\@FLAG\@/sprintf("0x%x", 1 << $flag_bit)/e;
$flag_bit ++;
}
print;
}
翻译如下:
enum foo {
A = @FLAG@,
B = @FLAG@,
C = @FLAG@,
};
对此:
enum foo {
A = 0x1,
B = 0x2,
C = 0x4,
};
如果您想将其与多个枚举类型一起使用,则可以使用本示例中未使用的 @RESET_FLAG@
语法来重置标志值。
您可以将其包含在构建过程中,例如,将 C 源文件命名为 foo.c.in
,并从 生成
通过在其上运行过滤器。foo.c
foo.c.in
请注意,过滤器不能处理一行上 @...@
的多次使用,并且如果标志数量超过 Perl 位数,过滤器将无法正常运行认为是整数。它还扩展了注释(应该不是问题)和字符串文字(可能是问题)中的 @FLAG@
。铃声、口哨和错误检查留作练习。
关于c - 如何在 C 中定义枚举标志,而不显式设置每个成员值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28509144/
我是一名优秀的程序员,十分优秀!