【问题标题】:Funny if condition in C有趣的if条件在C中
【发布时间】:2014-05-25 13:27:10
【问题描述】:

我正在尝试理解一些在 6 到 10 年前编写的又快又脏的 C/C++ 代码。

这个 if 表达式是什么意思?

int s_adr, e_adr, empf_adr;
// ...

if (success == OK &&
    (s_adr & 0x1f) == empf_adr &&
    (e_adr & 0x20) &&
    (s_adr & 0x20)
    )

(e_adr & 0x20)((e_adr & 0x20) == 1) 一样吗?或者我该如何理解?当您非常了解 C 和 C++ 时,我想这可能是一个愚蠢的问题。但我没有。

【问题讨论】:

  • 这不是 C++ 代码。在(e_adr & 0x20)(s_adr & 0x20) 之间至少缺少一个运算符。
  • 更像 (e_adr & 0x20) 等价于 ((e_adr & 0x20) !=0)
  • 不过,这确实是基本的 C。真 == 非零
  • @wolfgang 抱歉,我删除了 cmets 并杀死了 && :)
  • 在优化方面我可能有点邪恶:(e_adr & s_adr & 0x20)

标签: c++ c boolean boolean-logic


【解决方案1】:
e_adr & 0x20

等价于

( e_adr & 0x20 ) == 0x20

就是这个表达式检查是否在 e_adr 中设置了第 5 位(我从 LSB 开始计数从 0 开始的位)

我的意思是这个表达式用在与你的代码片段相关的 if 语句中。:)

【讨论】:

  • e_adr & 0x20 == 0x20 是错误的。实际上是(e_adr & 0x20) != 0
  • @Frank Bollack 你确定吗?:) 我的意思是在 if 语句中使用表达式
  • 嗯...就 logical 条件检查而言是正确的(即,您可以用什么替换 (e_addr & 0x20) 以达到相同的结果),但是((e_adr & 0x20) !=0) 更准确地表示真正检查的内容。
  • 真的吗?有什么区别?
  • @jsantander 我刚刚检查过:((0x20 & 0x20) == 0x20) 是真的,(0x20 & 0x20 == 0x20) 是假的。 0x20 == 0x20 首先被评估。
【解决方案2】:

& 是位运算,&& 是布尔运算。

例如,以下是显而易见的;

if (a && b) ...

但是,以下不是:

int a=1;
int b=2;
if (a & b) ...
if (a && b) ...

这两个 if 检查给出不同的结果。 C 中的布尔运算假定false0 并且true0 以外的任何东西。因此,上述代码中的布尔运算&& 将得到true

位运算&,但是对两个参数进行按位与。二进制 1 是 0001,二进制 2 是 0010。按位与执行以下操作

    0001
AND 0010
    ----
    0000

每个数字都经过“与”运算得到结果。

0001 和 0010 的按位或 (|) 将得到 0011。

【讨论】:

  • 我想0 = false, 1 = true。现在我看到0 = false, (!=0) = true。很高兴知道谢谢!
  • @mini-me 在某些语言中,这是正确的。然而,在 C 中,它不是。大多数人忽略的小事!
  • @mini-me:它实际上有点复杂,因为过渡不是对称的。 0 <-> false 是对称的,但是 (!=0) -> truetrue -> 1。布尔转换是有损的:)
  • @Trenin 什么不正确?在 C 中,逻辑运算符将所有非零值都视为真,不是吗?
  • @TannerSwett 你是对的——在 C 语言中,非零表示正确。我说的是 OP 的原始声明 (0 = false, 1 = true) 在 C 中不正确。可能应该更清楚。
【解决方案3】:

(e_adr & 0x20) 表示您正在检查 e_adr 右侧的第 6 位是否设置为 1。这当然不等于 1。例如,假设 e_adr 为 0x4430,(e_adr & 0x20) 变为 0x0020(在被解释为真或 1 的 if 条件下)。但是,如果 e_adr 为 0x4440,则 (e_adr & 0x20) 变为 0x0000(在被解释为 false 或 0 的 if 条件下)。

【讨论】:

  • OP 可能不知道 & 之类的位操作,并将其与逻辑操作 && 混淆。
【解决方案4】:

不,这两个条件是不一样的。 (e_adr & 0x20)(e_adr & 0x20) != 0 相同(实际上如果这个表达式的值不为零,它只能是0x20)。这有效地检查了e_adr 的第 6 个最低有效位是否非零。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多