有人可以解释一下while(foo)
与while(foo != NULL)
是如何等价的吗?也:
while(!foo)
与while(foo == NULL)
我知道不是,但这就是我所知道的。
假设foo
是指针类型,while (foo)
和while (foo != NULL)
是完全相同的。两者都等同于while (foo != 0)
。(在我看来,while (foo != NULL)
更清楚地表达了意图。
在任何需要条件的上下文中(if()
、while()
、其他几个(,如果条件比较不等于零,则表达式被视为真,如果比较等于零,则视为假。
NULL
是一个宏,可扩展为实现定义的 null 指针常量。将指针值与 NULL
进行比较会为空指针生成一个 true 值,对于任何非 null 指针,则为一个 false 值。
常量0
是空指针常量 [*]。(这并不意味着空指针具有相同的0x00000000
位表示形式或类似的东西,尽管它经常这样做;这意味着源代码中的常量0
可以表示空指针。如您所料,将指针值与空指针常量进行比较会告诉您该指针是否为空指针。在while (foo)
中,与零的比较是隐含的 - 但它仍然测试foo
是否为空指针。
更一般地说,while (foo)
将foo
与0
进行比较,这相当于将其与适当类型的"零"进行比较。 while (foo)
总是等同于while (foo != 0)
。对于浮点值,它也等效于 while (foo != 0.0)
。对于字符值,它等效于 while (foo != ' ')
。而且,正如我们所看到的,对于指针值,它等效于 while (foo != NULL)
.
(在 C 语言中,如果条件为假,则比较运算符总是产生0
int
值,如果条件为真,1
- 但通过隐式不等式与零的比较,任何非零值都被视为真。
[*] 空指针常量定义为值为 0
的整数常量表达式,或转换为 void*
的此类表达式。空指针常量不一定是指针类型,但将其转换为指针类型会生成空指针值。将指针值与0
进行比较会导致0
隐式转换为指针类型,以便可以进行比较。
while(foo);
和
while(foo != NULL)
等价,仅仅是因为 NULL 是一个扩展到 0
、 (void*)0
或 0L
的宏,假设在 C 0 中计算结果为 false(以及任何非零数为 true(,则
while(foo); //while foo isn't 0
while(foo != NULL) //expands to while(foo != 0) < while foo isn't 0
而 ( expression
( 只要expression
计算出任何非零值,就会重复封闭块。当expression
的计算结果为 0 时,while 循环结束。
如果指针值不是 std::nullptr
或 NULL
,则指针类型的expression
被视为非 0 。
!
运算符是布尔not
运算符。
因此
while (foo)
和
while (foo != NULL)
在逻辑上彼此等效。因此,两者的逻辑逆也相互等价。
NULL
是一个符号常量,你可以把它看作是一种替换文本。 NULL
只是编译器稍后用零替换的东西,因此编写while (foo != NULL)
与编写while (foo != 0)
相同。请记住,如果它左边的东西等于它右边的东西,==
说是,而如果它左边的东西不等于它右边的东西,!=
说是。
在 C 中,数字 0 总是表示假,其他每个数字都表示真。所以while (foo != 0)
就像说"在这个循环中运行代码,而foo是真的"。 例如,while (1)
与说"永远运行此循环中的代码"相同,因为 1 是一个始终不同于零的数字,因此始终为真。
在 C 语言中,如果你只使用foo
,其中需要真或假的值,它与说foo != 0
相同,这有点像您可以使用的快捷方式,它与询问"foo 是否为真?"相同。 !
的意思是"不是",所以问!foo
和问"foo不是真的吗?"是一样的,换句话说,"foo是假的吗?"。这意味着while (!foo)
与"当foo为false时在此循环中运行代码"相同,这与while (foo == 0)
相同,因为零表示false,这与while (foo == NULL)
相同,因为NULL
表示零。
可以这样想:循环中的代码只有在括号中的内容为 true(即非零(时才会运行。因此,在while (foo)
中,计算机会问"foo不是零吗?",如果是,循环将继续进行。现在,如果你有while (!foo)
,计算机会问"foo不是非零吗?",如果是,循环继续。仅当括号中的表达式导致 false 时,循环才会停止。
NULL
是在几个标准头文件中定义的,它不是像if
和while
这样的关键字,您需要包含一个定义它的头文件才能使用它。这个想法是,当指针指向地址零时,它被称为"空指针",这就是为什么它被称为NULL
,当你想说"零地址"而不仅仅是"零数字"时,它会使用。
编辑:正如马特·麦克纳布正确指出的那样,NULL
可以定义为0
或(void *)0
。为了避免任何疑问,我引用C11标准:
值为 0 的整数常量表达式或转换为类型 void * 的此类表达式称为空指针常量。
后来
宏 NULL 在
(和其他标头(中定义为空指针常量;请参阅 7.19。
然后,在第 7.19 节中:
3 宏是
零
它扩展到实现定义的空指针常量;和
偏移量(类型,成员指示符(
扩展到...
文字还在继续。因此,(void *)0
和0
是有效的实现定义的空指针常量。
while循环可以像这样运行:
while(1) //This will run forever.
while(true) //This will run forever.
NULL
就像 0,所以如果你有 while(foo != NULL)
,这是说 while(foo 不等于 0,所以虽然它等于 1 或其他什么(运行它。