Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 关于枚举和位运算_C++_C_Bit Manipulation_Enumeration - Fatal编程技术网

C++ 关于枚举和位运算

C++ 关于枚举和位运算,c++,c,bit-manipulation,enumeration,C++,C,Bit Manipulation,Enumeration,也许问题很简单 有一个枚举定义: enum uop_flags_enum { FICOMP = 0x001, FLCOMP = 0x002, FFCOMP = 0x004, FMEM = 0x008, FLOAD = 0x010, FSTORE = 0x020, FCTRL = 0x040, FCALL = 0x080,

也许问题很简单

有一个枚举定义:

enum uop_flags_enum {
  FICOMP        = 0x001,  
  FLCOMP        = 0x002,  
  FFCOMP        = 0x004, 
  FMEM          = 0x008, 
  FLOAD         = 0x010, 
  FSTORE        = 0x020, 
  FCTRL         = 0x040, 
  FCALL         = 0x080,  
  FRET          = 0x100, 
  FCOND         = 0x200  
};
代码中的某个地方有:

if (uop->flags & FCTRL)

当此条件为真且不为真时?

当在uop->flags中设置与FCTRL(0x040)对应的位时,此条件为真。&'是按位屏蔽,实际上屏蔽除FCTRL设置的位以外的所有位

这是一个枚举,用于为操作定义多个“标志”。您可以通过每个定义的值都是2的精确幂这一事实来推断这一点,因为它由一个值的单个位(“标志”)表示

此类型枚举的优点是,您可以使用以下命令组合任意多个标志:

你给出的条件,它使用


当且仅当设置了
FCTRL
标志时,即当设置了
uop->flags
的第7位时,为真。这是因为FCTRL==0x040==binary 01000000。

设置位时,条件为真。0x40是1000000,因此当设置
标志中的第7位时,它将为真。

最终,此代码检查
uop->flags
变量中是否启用了单个位(FCTRL标志)

但这里有一些解释:

如果(X)
检查X是否为“真”值,则代码
if(X)
会隐式地进行检查。 对于整数,0是唯一的“假”值,其他所有值都是“真”

因此,您的代码相当于:

if(0!=(uop->flags&FCTRL))

那是什么意思

&
运算符执行“按位AND”,这意味着左侧的每个位与右侧的相应位进行AND运算

如果我们用二进制写出两个操作数:

uop->flags      1010 1010  (example)

FCTRL           0100 0000
在本例中,如果对每对位执行“和”,则会得到以下结果:

result          0000 0000
其计算结果为false,在该示例中,
uop->flags
值未设置FCTRL标志

下面是另一个示例,其中设置了标志

uop->flags      1110 1010  (example)

FCTRL           0100 0000
相应的ANDed结果:

result          0100 0000

此结果为非零,因此为“true”,触发您的
if
语句。

因为枚举类型使用二进制数字的位置(即单位、2、4、8、16等),并且操作执行逻辑和。如果设置了该位,则该值将不会为零(true),否则将为false。

在这种情况下,每个下一个枚举项将左移1位,因此,只需检查
变量&flag==true
即可检查是否设置了某些标志。然而,如果我们想设置多位标志模式呢?比如说-

enum {
     #ifdef __GNUC__ // cool in GCC we can use binary constants
        myFlag = 0b1010
     #else           // otherwise fallback into integral constant mode
        myFlag = 10
     #endif
}
何时如何检查变量X是否设置了此标志?我们不能就这么做
X&myFlag==true
,因为例如
0b1000&myFlag==true
0b010&myFlag==true
——但0b1000和0b010都没有设置我们的两位!出于这个原因,我更喜欢完全检查位掩码,它允许在枚举中定义多位模式:

#define IS_BIT_MASK_SET(variable,flag) ((variable & flag) == flag)

uop->flags=0x140=>条件是否为真?有关按位操作的更多详细信息,请参阅。如果我想检查是否设置了FRET,我应该怎么做?@mahmood:
如果(uop->flags&FRET){/*FRET设置了*/}
enum {
     #ifdef __GNUC__ // cool in GCC we can use binary constants
        myFlag = 0b1010
     #else           // otherwise fallback into integral constant mode
        myFlag = 10
     #endif
}
#define IS_BIT_MASK_SET(variable,flag) ((variable & flag) == flag)