在C++中,"variable|variable"是什么意思?

7

我在研究这个ITE8712看门狗定时器演示代码时,发现了这个:

void InitWD(char cSetWatchDogUnit, char cSetTriggerSignal)
{
OpenIoConfig();     //open super IO of configuration for Super I/O

SelectIoDevice(0x07);   //select device7

//set watch dog counter of unit
WriteIoCR(0x72, cSetWatchDogUnit|cSetTriggerSignal);

//CloseIoConfig();      //close super IO of configuration for Super I/O
}

我想知道这行代码的含义:

cSetWatchDogUnit|cSetTriggerSignal

因为WriteIoCR函数的代码如下:
void WriteIoCR(char cIndex, char cData)
{
//super IO of index port for Super I/O
//select super IO of index register for Super I/O
outportb(equIndexPort,cIndex);

//super IO of data for Super I/O
//write data to data register
outportb(equDataPort,cData);
}

所以cIndex应该是0x72,但是cData呢?我真的不明白"|"这个符号,因为我只在条件语句中使用过它作为OR("||")。
5个回答

14

这是一种按位“或”运算,与普通的逻辑“或”不同。如果源变量中的任一对应位已设置,它就会在目标变量中设置相应位。

例如,表达式43 | 17可以计算为:

43 = 0x2b = binary 0010 1011
17 = 0x11 = binary 0001 0001
                   ==== ====
        "or" them: 0011 1011 = 0x3b = 59

请参考这个答案,对各种位运算符进行更全面的探讨。

它通常用于当您想要操作数据类型中的特定位时,例如在嵌入式系统中控制看门狗定时器(您的特定用例)。

您可以使用or (|)打开位,并使用and (&)关闭它们(使用反转的比特掩码来打开它们)。

因此,要打开b3位,请使用:

val = val | 0x08; // 0000 1000

要关闭它,请使用:

val = val & 0xf7; // 1111 0111

要检测是否设置了b3,请使用:

if ((val & 0x08) != 0) {
    // it is set.
}
通常会看到位掩码的定义如下:
#define B0 0x01
#define B1 0x02
#define B2 0x04
#define B3 0x08
#define B4 0x10

或者:

enum BitMask {
    B0 = 0x01,
    B1 = 0x02,
    B2 = 0x04,
    B3 = 0x08,
    B4 = 0x10
};

关于这意味着什么:

WriteIoCR (0x72, cSetWatchDogUnit|cSetTriggerSignal);
更有可能的是,0x72 是某种你要写入的输入/输出端口,而 cSetWatchDogUnitcSetTriggerSignal 则是位掩码,你需要将它们组合起来以输出命令(设置触发信号并使用一个单位值作为看门狗)。在实践中,这个命令的含义可以推断出来,但是更安全的做法是参考看门狗电路本身的文档。
如果你碰巧不知道看门狗电路的用途,它是一个简单的电路,如果你不经常激活它(使用另一个命令),它就会重置你的系统,可能通过激活你正在使用的任何处理器上的复位引脚来实现。
这是一种自动检测异常行为软件并将设备返回到已知初始状态的方式,符合这样的理论:与其继续执行错误,重新启动更好。

感谢您的输入并为其他事情付出额外的努力! - IBG

8

那是一个按位或操作符。它用于在这里组合标志。


1

x | y通常用于C/C++中的普通数据类型,表示按位或

例如:

char x = 0x1, y = 0x2;
x | y ==> 0x3

[注意:根据您的需要,可以为class/struct重载operator |]


1

| 是一个按位或运算符。如果两个整数中的同一位上有一个为1,则将该位切换为1(而不是0)。

|| 是逻辑或运算符。如果其中一个操作数为true,则返回true。


0

好的,这里是为什么在这种情况下使用位或或看到它们被使用的原因。

通常,这些变量是用于将多个数据打包成一个字符的标志。

如果cSetWatchDogUnitcSetTriggerSignal

具有不重叠的位(想象一下cSetWatchDogUnit = 1 << 0cSetTriggerSignal = 1 << 1),您可以稍后使用按位与检查它们是否设置,就像这个假设的例子:

if cData & cSetWatchDogUnit
    do something
if cData & cSetTriggerSignal
    do something else

整个过程中,这两个标志都可以打包成一个单一的字符并传递。这样,您就不会结束传递布尔数组,您可以添加新的常量cSetSomeOtherDamnfoolThing = 1 << 2,并且您可以在代码中将标志引用为变量。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接