这个C代码是什么意思? [短路评估]

时间:2015-07-05 16:26:53

标签: c logical-operators short-circuiting

Jeffrey Stedfast提出several functions that calculates the nearest power of 2。其中一个函数的代码如下:

static uint32_t
nearest_pow (uint32_t num)
{
  uint32_t j, k;
  (j = num & 0xFFFF0000) || (j = num); // What is this?
  ...
}

为了完全理解代码,我尝试将行更改为:

  j = num & 0xFFFF0000;
  j = j | (j = num);

无意中,我得到了正确的结果。但是,当我将这种转换应用到下一行(不包括在我的引文中)时,我得到了错误的结果。事实证明,我误解了代码的含义。

(j = num & 0xFFFF0000) || (j = num);是什么意思?

实际上,我需要将该函数转换为其他编程语言。

4 个答案:

答案 0 :(得分:1)

(j = num & 0xFFFF0000) || (j = num);

由于逻辑OR运算符的短路评估,如果j = num & 0xFFFF0000非0(TRUE),则j = num不会被评估;否则,j = num将在之后进行评估。

因此,整个语义是:

j = num & 0xFFFF0000;
if (j != 0) { // no operation
} else {
    j = num;
}

答案 1 :(得分:1)

  

(j = num& 0xFFFF0000)||是什么意思(j = num);?

a || b形式的某些内容会评估a,然后仅在b为假时评估a。换句话说,仅当j = num为false时才会评估j = num & 0xFFFF0000。如果表达式等于0,则表达式在C ++中被视为false,因此这相当于:

if ((j = num & 0xFFFF0000) == 0) {
    j = num;
}

或者,分开更多可能会让它更清晰:

uint32_t masked = num & 0xFFFF0000;
if (masked == 0) {
    j = num;
} else {
    j = masked;
}

答案 2 :(得分:1)

||是逻辑或操作员。它有一个短路行为,如果左侧为真,则不评估右侧(因为逻辑的结果或已知真实左侧的结果)。

在这种情况下,如果第一个作业j = num为零(“false”),则以环形交叉方式使用它来提供后备作业j = num & 0xFFFF0000。因此,首先将0xFFFF0000的高两个字节(掩码num)分配给j。如果这是零(“假”),即,高两个字节没有任何1位,则num被分配给j

实际上,这意味着“j如果它们非零则分配给num的高位字节,否则分配给j num的低两个字节”

答案 3 :(得分:1)

(j = num & 0xFFFF0000) || (j = num); 

j = num & 0xFFFF0000;
j = j | (j = num);

不等同,我不确定为什么会得到相同的结果。

  

(j = num& 0xFFFF0000)||是什么意思(j = num);?

在讨论确切含义之前,您必须知道logical or ||操作的评估顺序,该操作是从左到右的。在C中,零0表示布尔值false,任何其他非零值表示布尔值true。现在看下面的表达式,

left || right

如果lefttrue,则永远不会执行rightright仅在left为假时才会执行。

问题仍然存在,在这种情况下left将是假的?在这个表达式中:

(j = num & 0xFFFF0000) || (j = num);
如果(j = num & 0xFFFF0000)j分配,0表示num & 0xFFFF0000生成0,则

num & 0xFFFF0000将为false。

因此,如果0生成(j = num),那么正确的表达式将j执行,num最终由j = j | (j = num); 更新。故事结束。

  

现在以下代码意味着什么?

num

表示将j分配到|并使用之前的j执行bitwise or j,并将最终值重新分配到{{1}}。< / p>