while(foo) 与 while(foo != NULL)

while(foo) vs while(foo != NULL)

谁能解释一下 while(foo)while(foo != NULL) 是等价的?还有:

while(!foo) 对比 while(foo == NULL)

我知道!不是,但这就是我所知道的。

while (expression) 重复封闭块,只要 expression 的计算结果为任何非零值。当 expression 计算为 0 时,while 循环结束。

如果指针值不是 std::nullptrNULL.

,则指针类型的 expression 被认为是非 0

! 运算符是布尔值 not 运算符。

因此

 while (foo)

 while (foo != NULL)

在逻辑上是等价的。因此,两者的逻辑逆也等价。

while(foo);

while(foo != NULL)

是等价的,因为 NULL 是一个扩展为 0(void*)00L 的宏,假设在 C 中 0 的计算结果为假(以及任何非零数字为真)然后

while(foo); //while foo isn't 0
while(foo != NULL) //expands to while(foo != 0) < while foo isn't 0

while 循环可以 运行 像这样:

while(1) //This will run forever.

while(true) //This will run forever.

NULL 就像 0,所以如果你有 while(foo != NULL),这就是说 while(foo 不等于 0,所以 while 它等于 1 或其他东西) 运行它。

NULL是一个符号常量,你可以把它看成是一种替换文本。 NULL 只是编译器稍后用零替换的东西,所以写 while (foo != NULL) 和写 while (foo != 0) 是一样的。请记住,== 如果左边等于右边,则表示是,而 != 如果左边不等于右边,则表示是它。

在 C 语言中,数字 0 始终表示假,每隔一个数字表示真。所以 while (foo != 0) 等同于 "Run the code in this loop while foo is true"。例如,while (1) 与说 "Run the code in this loop forever" 是一样的,因为 1 是一个始终不同于零的数字,因此始终为真。

在 C 语言中,如果您只使用 foo,其中需要真假类型的值,这与说 foo != 0 相同,这有点像您可以使用的快捷方式,这与询问 "is foo true?" 相同。 ! 表示 "not",因此询问 !foo 与询问 "is foo NOT true?" 相同,换句话说 "is foo false?"。这意味着 while (!foo) 与 "Run the code in this loop while foo is false" 相同,与 while (foo == 0) 相同,因为零表示错误,与 while (foo == NULL) 相同,因为 NULL 表示零。

可以这样想:循环中的代码只会 运行 如果括号中的内容为真(即非零)。所以在 while (foo) 中,计算机将询问 "is foo non-zero?",如果是,则循环继续。现在,如果您有 while (!foo),计算机将询问 "is foo NOT non-zero?",如果是,则循环继续。只有当括号中的表达式结果为 false 时,循环才会停止。

NULL定义在几个标准的头文件中,它不是像ifwhile这样的关键字,你需要包含一个定义它的头文件才能使用它。这个想法是,当指针指向地址零时,它被称为 "null pointer",这就是为什么它被称为 NULL,当你想说 "zero the address" 而不仅仅是 "zero the number".

编辑: 正如 Matt McNabb 正确指出的那样,NULL 可以定义为 0(void *)0。为了避免任何疑问,我引用 C11 标准:

An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.

稍后

The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant; see 7.19.

然后,在第 7.19 节中:

3 The macros are

NULL

which expands to an implementation-defined null pointer constant; and

offsetof(type, member-designator)

which expands to...

文字还在继续。所以 (void *)00 是有效的实现定义的空指针常量。

假设foo是指针类型,while (foo)while (foo != NULL)是完全等价的。两者也等同于 while (foo != 0)。 (在我看来while (foo != NULL)更清楚地表达了意图。)

在任何需要条件的上下文中(if()while()、其他一些),如果条件比较不相等,表达式将被视为 true为零,false 如果它比较等于零。

NULL 是一个扩展为实现定义的 空指针常量 的宏。将指针值与 NULL 进行比较,空指针的值为真,非空指针的值为假。

常量0是一个空指针常量[*]。 (这并不意味着空指针具有与 0x00000000 相同的位表示或类似的东西,尽管它经常如此;它意味着源代码中的常量 0 可以表示空指针。)如您所料,将指针值与空指针常量进行比较可以告诉您该指针是否为空指针。在 while (foo) 中,与零的比较是隐含的——但它仍然测试 foo 是否为空指针。

更一般地说,while (foo)foo0 进行比较,相当于将其与适当类型的 "zero" 进行比较。 while (foo) 始终等同于 while (foo != 0)。对于浮点值,它也等同于 while (foo != 0.0)。对于字符值,它等同于 while (foo != '[=30=]')。而且,正如我们所见,对于指针值,它等同于 while (foo != NULL).

(在 C 语言中,如果条件为假,比较运算符总是产生 int0,如果条件为真,则产生 1 —— 但任何非零值都是通过与零的隐式不平等比较被视为真。)

[*] 空指针常量 被定义为具有值 0 的整型常量表达式,或此类表达式转换为 void*。空指针常量不一定是指针类型,但将其转换为指针类型会产生空指针值。将指针值与 0 进行比较会导致 0 隐式转换为指针类型,以便进行比较。