【问题标题】:Will a C conditional always return 1 or 0?C 条件总是返回 1 还是 0?
【发布时间】:2011-04-01 17:33:19
【问题描述】:

C 条件语句总是返回 [1 或 0],还是返回 [0 或“非零”]。我问是因为:

伪代码——

foo(地址,应该发送):
注册 >>= 1
register register |= shouldSend // 表示是否应该发送

如果有人传入一个大于 1 的 shouldSend 值,就会出现问题(因为只有 0 是假的,其他的都是真的,从技术上讲这是有效的)。因为我直接将 shouldSend 的真值与寄存器进行或运算,所以最好不要说 0xFF!我已经有了一个解决方案,所以这个问题更多是出于好奇。我想知道是否:

foo(地址,应该发送):
注册 >>= 1
register register |= (shouldSend > 0) // 表示是否应该发送

解决问题了吗?我认为现在传入的 0xFF(或通常大于 1 的东西)的问题被 C 条件掩盖了。但这仅适用于 IF C 条件保证返回 [0 或 1]。

ps - 我也意识到它可能依赖于编译器,但是 ansi 标准对此有何评论?

【问题讨论】:

  • 不应该是(应该发送!= 0)吗?使用 !!shouldSend 是一个邪恶的把戏。

标签: c standards conditional


【解决方案1】:

Standard 指定结果总是等于 0 或 1 的整数值

6.5.8关系运算符

每个运算符 (大于), = (大于或等于) 如果指定,则应产生 1 关系为真,如果是,则为 0 false.92) 结果的类型为 int。

【讨论】:

  • +1,令人惊讶的是它确实指定了该行为。随着时间的推移,我只是假设规范更有可能说“返回 0 或随机掷骰子”
  • 这导致了我在标准出现之前就使用过的成语:!!somevalue,它具有相同的真值,但现在可以保证正好是 0 或 1。
【解决方案2】:

是否指定无关紧要。最好始终针对 false 进行测试,并明确您的 or-equals 值。这消除了对编译器实现的任何担忧,并且更清晰,更易于维护。

【讨论】:

  • 这实际上是相关的,因为您可以使用 & 和 |运算符作为没有短路的逻辑运算符。
【解决方案3】:

我不会再次右移和左移以清除 LSB,而是按位 - 并使用 0xFE:

register = register & 0xFE;

[编辑:假设寄存器是 8 位。如果不是,请根据需要调整右手操作数]

但是是的,如果 shouldSend 是条件测试的结果,那么标准保证它是 0 或 1。如果对是否可以从其他任何地方生成 shouldSend 有任何疑问,明智的做法是放入你有什么预防措施,或者类似的东西

register = register | (shouldSend ? 1 : 0);

【讨论】:

  • 自从有了标准之前我就看到使用的成语:!!somevalue,它具有相同的真值,但现在可以保证正好是 0 或 1。
【解决方案4】:

是的。这在 C99 中得到保证。我手边没有 C89 规范。当然,众所周知,编译器实现者有时会犯错误,所以 YMMV。

C99 在6.5.8 关系运算符的第 6 段中指定以下内容:

每个运算符(小于)、>(大于)、(小于或等于)、如果指定的关系为真,则 >=(大于或等于)应为 1,如果为假,则为 0。

6.5.9 等式运算符的第 3 段、6.5.13 逻辑与运算符的第 3 段和的第 3 段中出现相同或相似的子句6.5.14 逻辑或运算符.

【讨论】:

  • 这在最初的 K&R C 中是正确的,并且经常依赖,因此标准必须效仿。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 2018-05-26
  • 2012-07-28
  • 2015-09-27
相关资源
最近更新 更多