【问题标题】:printf conversion specifier for _Bool?_Bool 的 printf 转换说明符?
【发布时间】:2012-06-30 07:22:03
【问题描述】:

使用printf(),我可以使用%hhu 代表unsigned char%hi 代表short int%zu 代表size_t%tx 代表ptrdiff_t,等等

p>

我对@9​​87654330@ 使用什么转换格式说明符?标准中是否存在一个?

或者我必须像这样投射它:

_Bool foo = 1;
printf("foo: %i\n", (int)foo);

【问题讨论】:

  • 我认为你不需要在 foo 前面进行转换:默认情况下,_Bool 将转换为 int
  • @RichardHansen 如果我没记错的话,默认提升总是适用于可变参数:浮点数变为双精度数,字符变为整数,等等。这可能在 C99 中有所改变,我不确定。
  • @Jack:我很怀疑——需要引用。 :) C99 6.3.1.1p1 说_Bool 的转换等级低于所有其他标准整数类型的等级,如果它是typedefed(对吗?),这不可能是真的。此外,6.3.1.2 描述了 _Bool 的特殊转换规则,如果 _Bool 只是将 typedefed 转换为 int,则该规则将不起作用。
  • @Jack 不,肯定不是;请不要发布虚假信息。当未声明参数的类型时,将应用默认提升,因此 _Bool 被隐式转换为 int。
  • @Jack: _Bool 绝对不是 int 的类型定义。 _Bool 是一个关键字,它是一个独特的类型。

标签: c standards printf c99


【解决方案1】:

_Bool 类型没有特定的转换长度修饰符。

_Bool 是一个 无符号 整数类型,其大小足以存储值 01。你可以这样打印_Bool

_Bool b = 1;
printf("%d\n", b);

由于整数提升规则,_Bool 保证提升为 int

【讨论】:

  • %u 也可以,特别是对于像我这样喜欢始终将无符号说明符与无符号类型一起使用的保持性类型。另外,我认为_Bool b = true; 更好用。
  • 这是目前最正确的答案——_Bool 将升级为int,而不是unsigned int。对于后代,如果答案包含对指定此行为的 C99 标准的引用,那就太好了。
  • 6.5.2.2p7 用于与省略号对应的参数的默认参数提升,6.5.2.2p6 用于默认参数提升的定义,6.3.1.1 用于整数提升
【解决方案2】:

在 C99 之前,bool 不是标准 C 的一部分,因此不作为 printf 修饰符存在。 C99,将 _Bool (您正在使用的)定义为整数,因此您应该可以将其转换为要显示的整数(至少从机器的角度来看)。或者,您可以执行以下操作:

printf("%d",foo?1:0);

【讨论】:

  • 或者如果你想打印一个字符串作为输出,你可以这样做:printf("foo: %s\n", foo ? "true" : "false");
  • 当然,该替代方案也有效,并且可能更易于键入。但是,我对打印_Bool 的各种方法不太感兴趣,而不是确认_Bool 没有长度修饰符或转换说明符。 (奖励将是一个关于它为什么不存在的讨论链接:监督?认为没有必要?)
  • 上述cmets中的回答是正确的:不需要强制转换,因为它是自动提升的......所以也不需要?:。而在 C99 之前没有 printf 修饰符这一事实是无关紧要的;他们本可以在添加 _Bool 时添加一个……但如果有,它会打印“true”或“false”。
  • @RichardHansen 您可以通过自己在线获取和阅读标准来确定有哪些 printf 格式以及更多内容,因为在官方标准之前和之后都有免费的工作草案......只需谷歌 C99 标准.
  • @RichardHansen 您也可以在线获取 C99 基本原理。但是,没有提到 _Bool 的 printf 格式(意料之中,因为它主要解释了为什么事情已经完成,而不是为什么没有完成)。
【解决方案3】:

正如您在对@Jack 的评论中所说,“6.3.1.1p1 表示_Bool 的转换排名低于所有其他标准整数类型的排名”。

在对printf 的调用中,charshort 将被提升并作为int(或unsigned int)在堆栈上传递,所以我认为使用%d 作为格式说明符会很好。这也意味着您不需要显式转换为int,因为这会自动发生。

唯一可能的问题是编译器如何表示_Bool,它可能是实现定义的,并且可能因编译器而异。我看到了两种可能的实现——0 和 1 或 0 和 -1。

为了最终的可移植性,请按照@user325181 的回答并使用三元组在两个选项之间进行选择。整数(编译器可能会优化掉)或字符串。

编辑:正如其他答案中所报告的,_Bool 被定义为可以存储 0 或 1 的无符号整数类型。因此,它将被提升为 unsigned int 传递给 printf() 时,我会说 %u%d 是最合适的说明符。

【讨论】:

  • 不可能将除01 (6.3.1.2) 之外的任何值存储到_Bool。所以转换回int 将(除非未定义的行为)总是产生01
  • @ecatmur:是的,<stdbool.h> 中的宏 falsetrue 分别扩展为 01
  • C 说_Bool 是无符号整数类型,所以-1 是不可能的。
  • @ecatmur 和 ouah:感谢您提供的信息,我已经更新了答案。
  • C99 6.3.1.1p2 说“如果int 可以表示原始类型的所有值,则将该值转换为int;否则,将其转换为unsigned int。 "由于int 可以表示_Bool 的所有值,因此它将被提升为int,而不是unsigned int(即使_Bool 是无符号整数类型)。
【解决方案4】:

没有。只需使用 %d%i 说明符,像 int 一样处理它。

_Bool

在 C99 中,引入了新的关键字 _Bool 作为新的布尔类型。 在许多方面,它的行为很像 unsigned int,但转换 从其他整数类型或指针总是被限制为 0 和 1。 除了其他无符号类型,正如人们所期望的那样 布尔类型,这种转换为 0 当且仅当表达式 question 评估为 0,在所有其他情况下为 1。标题 stdbool.h 提供了定义为的宏 bool、true 和 false _Bool,分别为 1 和 0。

想到的第一种实现方法是使用char 或(int8_tenumbit fields。但实际上,这取决于。它可以是typedef 用于int(正如我所提到的,它已被使用,但不推荐,受错误影响)或charunsigned int 或枚举和#define,这是常用的。

例如,Apple's implementation 使用 int,如您所见:

#ifndef _STDBOOL_H_
#define _STDBOOL_H_ 

#define __bool_true_false_are_defined   1

#ifndef __cplusplus

#define false   0
#define true    1

#define bool    _Bool
#if __STDC_VERSION__ < 199901L && __GNUC__ < 3
typedef int _Bool;
#endif

#endif /* !__cplusplus */

#endif /* !_STDBOOL_H_ */

其他实现:

typedef int8_t _Bool;

typedef enum { false = 0, true = 1 } bool;

typedef unsigned char Boolean; typedef _Bool Boolean;

【讨论】:

  • 这些实现都不是 C99。 _Bool 是 C99 中的关键字,您不会在任何标题中找到它的定义。在上面的 Apple 示例中,它为 C99 之前的 C 版本定义了它。在您的其他示例中,您有一个 bool 类型和一个定义为 unsigned char_BoolBoolean 类型。
【解决方案5】:

我将%b 用于Java printf() 转换说明符。我最近尝试过,令我惊讶的是它成功了。

这是代码行:

System.out.printf("firstRobot == secondRobot: %b",firstRobot == secondRobot);

这是输出:

firstRobot == secondRobot: false

【讨论】:

    猜你喜欢
    • 2013-07-22
    • 1970-01-01
    • 2011-05-23
    • 2014-01-07
    • 2017-11-16
    • 1970-01-01
    • 2012-03-14
    • 1970-01-01
    • 2013-12-20
    相关资源
    最近更新 更多