如果我想打印
bool
var 值但我在 printf 格式字符串中使用了 %f
和 %s
怎么办?代码如何工作?
bool a =true;
bool b ="true";
bool c ='\0';
bool d ="\0";
printf("%d\n",a);
printf("%d\n",b);
printf("%d\n",c);
printf("%d\n",d);
printf("%s\n",a);
printf("%s\n",b);
printf("%s\n",c);
printf("%s\n",d);
printf("%f\n",a);
printf("%f\n",b);
printf("%f\n",c);
printf("%f\n",d);
名称
bool
是标准无符号整数类型的宏名称_Bool
.
来自C标准(6.2.5类型)
- ...类型_Bool和对应标准有符号整数类型的无符号整数类型为标准无符号整数 类型
and (7.18 布尔类型和值
2 宏 bool 扩展为 _Bool。 3 剩下的三个宏适合在#if预处理中使用 指令。它们是
扩展为整数常量true
,1
扩展为整数常量false
,...0
并且类型
_Bool
的对象可能只有两个值之一(6.2.5类型)
2 声明为类型 _Bool 的对象足够大以存储值 0 和 1.
发生以下表达式到类型
_Bool
的转换(6.3.1.2布尔类型)
1 当任何标量值转换为_Bool 时,如果 值比较等于 0;否则,结果为 1.
在您的代码片段中,有
_Bool
类型的初始化对象
bool a =true;
bool b ="true";
bool c ='\0';
bool d ="\0";
来自C标准(6.7.9初始化)
11 标量的初始值设定项应为单个表达式, 可选地括在大括号中。 对象的初始值为 表达式的(转换后);同类型约束 和简单赋值的转换适用,采用类型 标量是其声明类型的非限定版本
和(6.5.16.1简单赋值)
1 满足以下条件之一: .... — 左操作数的类型为原子、限定或非限定 _Bool, 右边是一个指针。
这两个声明
bool a =true;
bool c ='\0';
相当于
bool a = 1;
bool c = 0;
这两个声明等同于
bool b = "true" != 0;
bool d ="\0" != 0;
在这些声明中,字符串文字被隐式转换为指向其第一个元素值不等于 0 的指针。所以实际上上面两个声明可以重写为
bool b = 1;
bool d = 1;
printf
的这些电话
printf("%d\n",a);
printf("%d\n",b);
printf("%d\n",c);
printf("%d\n",d);
是正确的。使用转换说明符
d
的无符号整数类型 _Bool 的输出值可以适合有符号类型 int
. 的对象
printf
的所有其他调用都是不正确的,因为使用了转换说明符 s
旨在输出字符串而不是整数,而转换说明符 f
旨在输出双精度类型的对象而不是整数
printf("%s\n",a);
printf("%s\n",b);
printf("%s\n",c);
printf("%s\n",d);
printf("%f\n",a);
printf("%f\n",b);
printf("%f\n",c);
printf("%f\n",d);
所以这些调用会调用未定义的行为。
解决方案是改变你的方法。
与其试图将各种值强加到一个
bool
变量中(无论您使用的是什么 bool
....),您应该使用具有适当类型的变量来存储您想要存储的内容。例如。 '\0'
进入 char
类型的变量。
然后,当您要打印该值时,使用与该值和可变数据类型匹配的格式说明符就不是问题了。
当您想将这些值用作布尔值时(基本上您不能直接这样做),您可以在像
if('\0' == myCharBool)
这样的布尔表达式上创建一个条件,并且在该{}else{}
的两个if
分支中,您可以做任何可能的结果真/假。
记住在 C 中,
0
是假的。其他一切都是真的。从stdbool.h
,true
是1
和false
是0
.
因此,在您的示例中,
b
为真,因为字符串文字衰减为指向其第一个元素的指针。这不会是0
。 c
是假的,因为 '\0'
是 0
。 d
是真的,因为我们再次将指针分配给字符串文字 "\0"
.
当您打印时,您应该得到一长串警告,对应于每次尝试将整数类型 (
bool
) 打印为非整数的尝试。它 might 实际上有效,但你已经进入了未定义行为的领域。
实际上,您不太可能在非平凡的程序中直接打印
bool
。您将使用它来确定您想要打印的内容。