这段C代码是什么意思? [短路评估]
What is the meaning of this C code? [short-circuit evaluation]
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);
是什么意思?
实际上,我需要将函数转换为其他编程语言。
(j = num & 0xFFFF0000) || (j = num);
由于逻辑或运算符的短路计算,如果 j = num & 0xFFFF0000
为非 0 (TRUE),则不会计算 j = num
;否则,j = num
将在之后进行评估。
因此,整个语义是:
j = num & 0xFFFF0000;
if (j != 0) { // no operation
} else {
j = num;
}
What is the meaning of (j = num & 0xFFFF0000) || (j = num);?
a || b
形式的内容将计算 a
,然后仅当 a
为假时才计算 b
。换句话说,只有当 j = num & 0xFFFF0000
为 false 时,才会计算 j = num
。如果表达式等于 0,则表达式在 C++ 中被视为假,因此这等同于:
if ((j = num & 0xFFFF0000) == 0) {
j = num;
}
或者,分解更多可能会使它更清晰:
uint32_t masked = num & 0xFFFF0000;
if (masked == 0) {
j = num;
} else {
j = masked;
}
||
是逻辑或运算符。它具有短路行为,因此如果左侧为真,则不评估右侧(因为逻辑 or 的结果已经从真正的左侧已知为真)。
在这种情况下,如果第一个赋值 j = num & 0xFFFF0000
为零(“false”),则以迂回方式使用它来提供后备赋值 j = num
。因此,首先将 num
的高两个字节(掩码 0xFFFF0000
)分配给 j
。如果这是零(“假”),即高两个字节没有任何 1 位,则 num
被分配给 j
.
实际上这意味着“如果它们不为零,则将 num
的高两个字节分配给 j
,否则将 num
的低两个字节分配给 j
]”.
(j = num & 0xFFFF0000) || (j = num);
并且,
j = num & 0xFFFF0000;
j = j | (j = num);
不等价,我不确定为什么你会得到相同的结果。
What is the meaning of (j = num & 0xFFFF0000) || (j = num);?
在讨论它的确切含义之前,您必须了解 logical or ||
操作的评估顺序,即从左到右。在 C 中,零 0
表示布尔值 false
,任何其他非零值表示布尔值 true
。现在看下面的表达式,
left || right
如果left
是true
那么right
永远不会被执行,right
只有当且仅当left
是false时才会执行。
问题仍然存在,在这种情况下 left
将是错误的?在这个表达式中:
(j = num & 0xFFFF0000) || (j = num);
(j = num & 0xFFFF0000)
如果 j
被赋值为 0
则为 false 意味着 num & 0xFFFF0000
产生 0
。
所以如果 num & 0xFFFF0000
产生 0
那么正确的表达式将执行 (j = num)
并且 j
最后由 num
更新。故事结束。
Now what the following code means?
j = j | (j = num);
意思是,把num
赋值给j
,然后用前面的j
执行bitwise or|
,最后的值重新赋值给j
.
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);
是什么意思?
实际上,我需要将函数转换为其他编程语言。
(j = num & 0xFFFF0000) || (j = num);
由于逻辑或运算符的短路计算,如果 j = num & 0xFFFF0000
为非 0 (TRUE),则不会计算 j = num
;否则,j = num
将在之后进行评估。
因此,整个语义是:
j = num & 0xFFFF0000;
if (j != 0) { // no operation
} else {
j = num;
}
What is the meaning of (j = num & 0xFFFF0000) || (j = num);?
a || b
形式的内容将计算 a
,然后仅当 a
为假时才计算 b
。换句话说,只有当 j = num & 0xFFFF0000
为 false 时,才会计算 j = num
。如果表达式等于 0,则表达式在 C++ 中被视为假,因此这等同于:
if ((j = num & 0xFFFF0000) == 0) {
j = num;
}
或者,分解更多可能会使它更清晰:
uint32_t masked = num & 0xFFFF0000;
if (masked == 0) {
j = num;
} else {
j = masked;
}
||
是逻辑或运算符。它具有短路行为,因此如果左侧为真,则不评估右侧(因为逻辑 or 的结果已经从真正的左侧已知为真)。
在这种情况下,如果第一个赋值 j = num & 0xFFFF0000
为零(“false”),则以迂回方式使用它来提供后备赋值 j = num
。因此,首先将 num
的高两个字节(掩码 0xFFFF0000
)分配给 j
。如果这是零(“假”),即高两个字节没有任何 1 位,则 num
被分配给 j
.
实际上这意味着“如果它们不为零,则将 num
的高两个字节分配给 j
,否则将 num
的低两个字节分配给 j
]”.
(j = num & 0xFFFF0000) || (j = num);
并且,
j = num & 0xFFFF0000;
j = j | (j = num);
不等价,我不确定为什么你会得到相同的结果。
What is the meaning of (j = num & 0xFFFF0000) || (j = num);?
在讨论它的确切含义之前,您必须了解 logical or ||
操作的评估顺序,即从左到右。在 C 中,零 0
表示布尔值 false
,任何其他非零值表示布尔值 true
。现在看下面的表达式,
left || right
如果left
是true
那么right
永远不会被执行,right
只有当且仅当left
是false时才会执行。
问题仍然存在,在这种情况下 left
将是错误的?在这个表达式中:
(j = num & 0xFFFF0000) || (j = num);
(j = num & 0xFFFF0000)
如果 j
被赋值为 0
则为 false 意味着 num & 0xFFFF0000
产生 0
。
所以如果 num & 0xFFFF0000
产生 0
那么正确的表达式将执行 (j = num)
并且 j
最后由 num
更新。故事结束。
Now what the following code means?
j = j | (j = num);
意思是,把num
赋值给j
,然后用前面的j
执行bitwise or|
,最后的值重新赋值给j
.