【问题标题】:Addition with _Bool type in C在 C 中添加 _Bool 类型
【发布时间】:2020-08-14 22:56:49
【问题描述】:

在我正在编写的一段代码中,如果某些_Bool 为真,我需要在unsigned long 上加1。

我一直在用

unsigned long l;
_Bool b;
... //stuff happens to both variables
if(b)
    ++l;

但我在 C 标准中读到 _Bool 类型被归类为“标准无符号整数类型”之一,并且保证将 true 表示为 1,false 表示为 0。

我用这个看似等效的表达式替换了我的代码

unsigned long l;
_Bool b;
... //stuff happens to both variables
l+=b;

我的编译器没有抱怨,它似乎运行良好。

这是保证工作,还是我只是在我的编译器中利用 _Bool 的实现?

【问题讨论】:

  • 保证工作
  • 你不能保证总是有 "_Bool" ...但如果你这样做了,你的代码就可以工作。如果你不这样做,它甚至不会编译:) 问:你为什么用“真/假”做整数运算?这难道不是首先破坏了拥有“_Bool”的目的吗????
  • @paulsm4 C99 及更高版本绝对保证_Bool 的存在。没有它的唯一方法是如果您有一个不符合标准的编译器或符合 C90 的编译器。如今,这样的编译器很少见。可能有一些适用于小型嵌入式系统。

标签: c boolean


【解决方案1】:

几乎保证可以工作。

标准并没有说_Bool对象只能保存值0和1。实际上sizeof(_Bool)至少是1,这意味着它至少有8位,这意味着它可以原则上至少包含 256 个不同的值。

如果您为b 赋值的代码是合理的,您可以放心地假设它的值是0 或1。从其他类型到_Bool 的所有转换都保证产生0 或1 的值。

但是您可以在 _Bool 对象中存储 0 或 1 以外的值,尽管这样做的任何方法都可能具有未定义的行为。

一个例子:

#include <stdio.h>
#include <string.h>
int main(void) {
    _Bool b;
    char c = 42;
    memcpy(&b, &c, 1);
    long n = 0;
    n += b;
    printf("n = %ld\n", n);
}

我系统上的输出是

n = 42

但只要你不做这种愚蠢的事情,并以最低限度的尊重对待_Bool,你应该没问题。

【讨论】:

  • 你为什么要memcpyONY BYTE?
  • @user14107922 -- 因为b_Bool。使用b = c 将进行隐式转换,b 将获得值1。但该示例的重点是,可以在_Bool 中存储除01 之外的值other。你可能还会注意到分手:“……只要你不做这种傻事,……
  • @exnihilo 除了对一个字节进行memcpy 调用之外,还有更有效的方法来避免隐式版本吗?
  • @user14107922 -- 这不是我的答案,所以你应该问问发帖人。但是,memcpy 的效率很高,否则您将如何在避免赋值的同时复制值?
  • 我看到@user14107922 已经没有账号了,不过我还是会回答的。你可能不会memcpy 一个字节,虽然你可能memcpy N 个字节,其中 *NN 恰好是 1。但关键是它有可能编写很可能在 _Bool 类型的对象中存储除 0 或 1 之外的值的代码。
【解决方案2】:

这能保证工作吗

是的,C 中的布尔值只是整数,因此在我所知道的任何编译器下,向整数添加布尔值都是完全可以接受的。 C 是弱类型的,因此布尔值和整数值之间没有明显区别。声明为_Bool 的变量的唯一意义是它会自动将分配给它的任何值转换为 1 或 0。

_Bool x = 3; //x will be 1
int y = 7;
int z = y + x; //z will be 8

【讨论】:

    猜你喜欢
    • 2012-02-02
    • 2019-02-09
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-20
    相关资源
    最近更新 更多