Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么是C++;允许算术或枚举值隐式转换为布尔值?_C++_Boolean - Fatal编程技术网

C++ 为什么是C++;允许算术或枚举值隐式转换为布尔值?

C++ 为什么是C++;允许算术或枚举值隐式转换为布尔值?,c++,boolean,C++,Boolean,C++标准在第4.12节中说 算术、枚举、指针或指向成员类型的指针的右值可以转换为bool类型的右值。零值、空指针值或空成员指针值将转换为false,其他值将转换为true 这意味着以下代码是有效的 if(5) std::cout << "WOW!"; if(5) 我认为这是历史性的,是C用来评估布尔类概念的副产品 C过去没有布尔类型,在C的“精确到金属”范例中,设置为NULL的指针和数字类型等也隐式地false 如果你认为它是‘nothing/zero==false’和‘an

C++标准在第4.12节中说

算术、枚举、指针或指向成员类型的指针的右值可以转换为bool类型的右值。零值、空指针值或空成员指针值将转换为false,其他值将转换为true

这意味着以下代码是有效的

if(5)
  std::cout << "WOW!";
if(5)
我认为这是历史性的,是C用来评估布尔类概念的副产品

C过去没有布尔类型,在C的“精确到金属”范例中,设置为NULL的指针和数字类型等也隐式地
false


如果你认为它是‘nothing/zero==
false
’和‘anything other=
true
’,它实际上是有意义的。

事实上,在许多语言中,包括C/Python/Perl/BASIC非零整数/指针值 始终被视为真,0被视为假

这是许多编程语言中已知的约定,所以没有理由,为什么这不能在C++中?< /P>


问题是为什么在Java中不是这样?

它来自C的产品

另外请注意,这些(逻辑上,如果不是计算上)是等效的:

if(x&y | | z)

如果(x*y+z)


(我之所以知道这一点,是因为TI99/4a BASIC没有AND或OR操作,所以*和+必须执行双重任务,而在TI99/4a BASIC中,布尔值与C中的一样工作。

这是特定硬件限制的产物

术语“int”、“short”、“bool”等只有在编译器工作时才有真正不同的语义含义——在运行时,它只是一个1字(8位)值、2字(16位)值、4字(32位)值等等


所以这里真正的问题不是“为什么C++除了5是布尔值”,而是“为什么c?”和答案是,由于内存对齐,在任何情况下都不可能在任何地方存储一个比特,所以编译器只使用了一个整字。C++中的类型只是一些词汇的挥手。

这是猜测,但我相信这是因为C被设计为极简语言。

首先,布尔评价和算术求值非常相似,它们实际上是在C解析器中组合的,这就减少了分析器-C++继承的整体大小。


其次,汇编中非零结果的测试通常使用单个操作码来执行,该操作码测试寄存器的零值,如果为真,则跳转到语句的“else”部分。如果值为非零,则执行自然会进入语句的“if为真”部分。

历史上,C是一个相对独立的、专为sim设计的操作码Pascal和类似的语言是更强类型的——枚举、指针、整数和布尔不能在表达式中随机混合和匹配

C(以及许多C++)程序员就是在这种背景下成长起来的,您经常会看到这样的惯用代码:

while (1)
   dosomething(); // repeats forever
……或者

char * pointer;

if (pointer)  // tests pointer for being != 0, which equals NULL.
  fred = *pointer;

P>个人,尽管使用C++ C++ C++已经超过20年,但我仍然发现第二个习语很难看,因为它在一行中产生了两个“隐藏”的C++模型,即(null=0),并且(0 ==false)。引入不允许隐式转换为整数的作用域枚举,从而导致以下代码格式错误

enum class X { A, B, C };
if(X::B) { ... }
虽然数字允许隐式转换为bool对我来说是有意义的,但对枚举来说没有多大意义,因为主要目的是枚举一个值列表-我相信大多数时候只对枚举数的第二个实值感兴趣。作用域枚举将需要强制转换

if(static_cast<bool>(X::B)) { ... }
if(static_cast(X::B)){…}

这增加了一些类型安全性,这是目前为止枚举所需的C兼容性所不允许的(我想如果禁止普通枚举,这会破坏很多代码).

我找不到确切的引文,但人们总是说C将汇编语言的所有功能和灵活性与汇编语言的安全性和易用性结合在一起

通常处理器没有布尔型、整数型和ptr型。它们都只是内存或寄存器中的数字

就我个人而言,我一直喜欢这个成语:

some_obj * thingy;
if (thingy) ...
这似乎是表达“thingy exists”或“is initialized”的一种自然而简洁的方式。但后来,我花了很多时间在汇编语言上

虽然我确实倾向于在Objective-C、Java、C#中使用“thingy==null”(或nil),因为你只是觉得这些语言中发生的事情有点不太确定,离硬件更远。在某些语言中,甚至有人可以覆盖“==”操作符


你可以把“if(ptr)…”想象成调用一个隐式的“cast to boolean”操作符…

这里有很好的答案,但我想指出一件事:即使你不能说
boolean=number
boolean=pointer
,但使用
if(number)
if(pointer)仍然有意义
构造。

可能是为了迫使程序员在逻辑条件中显式,使代码更具可读性。这只是胡扯。不是一个真正的问题。Poster有一段不错的历史-什么让你认为这不是真实的?对于世界各地成群结队的用C(或汇编语言)长大的程序员来说,这在语义上是有意义的我不认为这是一个怪人的问题。我喜欢它-经常想知道为什么会这样。不是这样。如果x==1和y==1,那么x | | y是真的,但是x+y是假的。C使用0==false,而不是0==true的原因是处理器实际上没有任何数据类型-只是不同大小的寄存器(如果幸运的话).硬件支持的“布尔”运算在寄存器中归结为0或不为0。C只是让程序员可以看到它。记住