【问题标题】:What advantage does _Bool give?_Bool 有什么优势?
【发布时间】:2021-01-10 05:32:40
【问题描述】:

如果_Bool 类型的行为类似于整数并且不强制值是真/假或 1/0,例如:

_Bool bools[] = {0,3,'c',0x17};
printf("%d", bools[2]);

> 1

在那里有什么好处?这是否只是一种简单的强制事物以查看它们如何评估“真实性”的方法,例如:

printf("%d\n", (_Bool) 3);
> 1

或者这对 C 语言有什么帮助或用处?

【问题讨论】:

  • 据我所知,您不应该将它与前缀一起使用,这是一个实现细节。使用bool
  • @tadman C 语言,因为 C99 有 _Boolbool<stdbool.h> 中定义为_Bool 的宏。
  • @chux-ReinstateMonica 当然,但这并不意味着使用文字 _Bool 是一个好计划。这是一种帮助人们适应“新”标准的变通方法。希望 21 年后人们已经准备好了。
  • @tadman _Bool 不是实现细节。它是标准接口的一部分。
  • @AyxanHaqverdili 据我了解,这是一种通过声明新关键字来避免在 C 中引入“破坏性”更改的方法。这不是你想故意使用的东西。这是一个标准化的东西,但它也是一个“内部”,因为你直接使用它是不寻常的。

标签: c boolean


【解决方案1】:

_Bool 有什么优势?

  1. _Bool 的值是 0 或 1。没有别的,不像 int

  2. 转换为_Bool 始终会将非零转换为 1,仅将 0 转换为 0。

当任何标量值转换为_Bool时,如果该值比较等于0,则结果为0;否则,结果为 1。

例子:

#include <math.h>
#include <stdlib.h>
_Bool all_false[] = { 0, 0.0, -0.0, NULL };
_Bool all_true[] = { 13, 0.1, 42.0, "Hello", NAN };

注意转换/强制转换为int 与; _Bool: (int) 0.1 --> 0,然而(_Bool) 0.1 --> 1.

注意转换/强制转换为unsigned 与; _Bool: (unsigned) 0x100000000 --> 0,然而(_Bool) 0x100000000 --> 1.

  1. _Bool 增加布尔运算的清晰度。

  2. _Boolintchar 等在与 _Generic 一起使用时是一个独特的类型。

  3. 在 C99 之前,C 缺少 _Bool。许多早期代码形成了自己的类型bool, Bool, boolean, bool8, bool_t, ...。创建一个新类型_Bool 为这种常见但不统一的做法带来了统一性。 &lt;stdbool.h&gt; 可以使用 bool, true, false。这允许不包括 &lt;stdbool.h&gt; 的旧代码不会中断,但新代码可以使用更简洁的名称。


OP 的“不强制值为真/假或 1/0”的示例确实强制 bools[2] 的值为 1。它没有强制 'c' 的初始化程序,@987654347 @,必须在 [0...1] 范围内,也不属于 _Bool 类型,就像允许 int x = 12.345; 一样。在这两种情况下,都发生了转换。虽然第 2 次经常会产生警告。

【讨论】:

  • 谢谢,你能解释一下为什么(unsigned) 0x1 0000 0000会变成0吗?默认情况下不是无符号4字节吗?
  • @David542 unsigned 被指定为至少 16位。它通常是 32 位的。 0x1 0000 0000 是一个 33 位值。将其转换为 32 位或 16 位 unsigned 会缩小其值。实际上切断了领先1,留下0。将0x1 0000 0000转换/转换为_Bool是1。
  • 对不起,我看错了。我看到了 9 0/1 并认为是布尔值,但现在我看到了 0x 前缀。感谢您指出这一点。
  • @David542 Boolean 类型的缺失被认为是 C 的一个缺点。C99 添加了它,并且普遍受到好评。我不喜欢_Bool 的一个独特方面是它的大小未指定为 1。它通常为 1 或有时与int 的大小相同。我从未见过_Bool 的任何其他尺寸。
  • 逻辑表达式的计算结果为int 而不是_Bool,这有点奇怪。所以a != bint。这可能对_Generic 很重要。
【解决方案2】:

优点是易读性,仅此而已。例如:

bool rb() {
  if (cond && f(y)) {
    return true;
  }

  return false;
}

对比:

int rb() {
  if (cond && f(y)) {
    return 1;
  }

  return 0;
}

它真的没有其他好处。对于那些习惯在没有bool 的情况下使用 C 代码的人来说,这在很大程度上是一种装饰,但对于那些习惯于 C++ 及其bool 的人来说,它可能会让编码感觉更加一致。

与往常一样,“转换为布尔值”的简单方法就是双重否定,例如:

!!3

这会将其减少到 01 值。

【讨论】:

  • sizeof(bool)sizeof(int) 相比是什么? C 是否允许位域打包使得sizeof(bool[8]) == sizeof(char)
  • 我不确定是否有任何 C 实现可以像 C++ 那样使用 std::vector&lt;bool&gt; 专业化进行打包。似乎它只是使用可以保存01 值的smallest convenient unit,在大多数情况下是一个字节。如果你有一些 4 位字长的古怪机器,它会是其中之一。
  • @tadman 'cast to boolean' 被认为是更好的实践——做(bool) val!!val
  • 这真的取决于你是否首先需要,但如果你必须,那么双重否定通常可以完成这项工作,尽管你在 C 代码中看到的几乎没有你看到的那么多在诸如 Ruby 和 JavaScript 之类的东西中,它们的布尔类型更正式地表达。
  • 没有必要强制转换为bool 并且!!val 的技巧很丑陋而且有点令人困惑。更好地表达你真正想说的val != 0
【解决方案3】:

考虑一下

(bool) 0.5 -> 1
( int) 0.5 -> 0

如您所见,_Bool 不像整数。

【讨论】:

    猜你喜欢
    • 2010-09-19
    • 2012-12-19
    • 2010-09-08
    • 2012-11-30
    • 2013-04-08
    • 2014-10-04
    • 2017-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多