我有一小段关于sizeof
运算符和三元运算符的代码:
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool a = true;
printf("%zu\n", sizeof(bool)); // Ok
printf("%zu\n", sizeof(a)); // Ok
printf("%zu\n", sizeof(a ? true : false)); // Why 4?
return 0;
}
输出():
1
1
4 // Why 4?
但在这里,
printf("%zu\n", sizeof(a ? true : false)); // Why 4?
三元运算符返回boolean
类型,而bool
类型的大小是C中的1
字节。
那么为什么 sizeof(a ? true : false)
会给出四个字节的输出呢?
发布于 2017-10-30 16:42:47
那是因为你有#include <stdbool.h>
该标头将true
和false
设置为1
和0
,因此语句如下所示:
printf("%zu\n", sizeof(a ? 1 : 0)); // Why 4?
在您的平台上,sizeof(int)
是4。
发布于 2017-10-31 17:47:52
关于C中的布尔类型的
布尔类型在C语言中引入得相当晚,是在1999年。在此之前,C没有布尔类型,而是对所有布尔表达式使用int
。因此,所有逻辑运算符,如> == !
等,都会返回值为1
或0
的int
。
对于应用程序来说,使用自制类型是一种定制,比如typedef enum { FALSE, TRUE } BOOL;
,它也归结为int
-sized类型。
C++有一个更好的显式布尔类型bool
,它不超过1个字节。而C中的布尔类型或表达式在最坏的情况下会以4个字节结束。在使用C99标准的C语言中引入了与C++的某种兼容性。然后,C获得了一个布尔类型_Bool
和头文件stdbool.h
。
stdbool.h
提供了与C++的一些兼容性。此标头定义扩展为_Bool
的宏关键字(拼写与C++关键字相同),这是一种小整数类型,可能有1个字节大。类似地,头文件提供了两个宏true
和false
,拼写与C++关键字相同,但与旧的C程序向后兼容。因此,true
和false
在C中扩展为1
和0
,它们的类型是int
。这些宏实际上不像相应的C++关键字那样是布尔型的。
类似地,出于向后兼容的目的,C中的逻辑运算符至今仍返回int
,即使现在的C使用的是布尔类型。而在C++中,逻辑运算符返回一个bool
。因此,像sizeof(a == b)
这样的表达式将在C中给出int
的大小,但在C++中给出bool
的大小。
关于条件运算符?:
的
条件运算符?:
是一个奇怪的运算符,有几个怪癖。认为它100%等同于if() { } else {}
是一种常见的错误。不完全是。
在第一个操作数和第二个或第三个操作数的求值之间有一个序列点。?:
运算符保证只计算第二个或第三个操作数,因此它不能执行未计算的操作数的任何副作用。像true? func1() : func2()
这样的代码不会执行func2()
。到现在为止还好。
然而,有一条特殊的规则规定,第二个和第三个操作数必须通过通常的算术转换进行隐式类型升级和相互平衡。(Implicit type promotion rules in C explained here)。这意味着第二个或第三个操作数将始终至少与int
一样大。
所以在C中,true
和false
恰好是int
类型并不重要,因为表达式总是至少给出一个int
的大小。
即使您将表达式重写为 int
,它仍将返回int
的大小!
这是因为通过通常的算术转换进行隐式类型提升。
发布于 2017-10-31 17:02:31
快速回答:
sizeof(a ? true : false)
的计算结果为4
,因为true
和false
在<stdbool.h>
中分别定义为1
和0
,因此表达式扩展为sizeof(a ? 1 : 0)
,这是一个int
类型的整数表达式,在您的平台上占用4个字节。出于同样的原因,在您的系统上,sizeof(true)
也会评估为4
。但是,请注意:
sizeof(a ? a : a)
的计算结果也为4
,因为如果第二个和第三个操作数是整数表达式,则三元运算符会对这些操作数执行整数提升。当然,sizeof(a ? true : false)
和sizeof(a ? (bool)true : (bool)false)
也会发生同样的情况,但将整个表达式转换为bool
的行为与预期不谋而合:sizeof((bool)(a ? true : false)) -> 1
.1
或0
,但类型为int
:sizeof(a == a) -> 4
.保持a
布尔性质的唯一运算符是:
sizeof(a, a)
和sizeof(true, a)
在编译时的计算结果都是1
。sizeof(a = a)
和sizeof(a = true)
的值都是1
递增运算符:最后,以上所有内容仅适用于C语言: C++对于bool
类型、布尔值true
和false
、比较运算符以及三元运算符具有不同的语义:所有这些sizeof()
表达式在C++中的计算结果都是1
。
https://stackoverflow.com/questions/47010910
复制相似问题