C语言 while(foo) vs while(foo != NULL)



有人可以解释一下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)foo0进行比较,这相当于将其与适当类型的"零"进行比较。 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*)00L 的宏,假设在 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::nullptrNULL ,则指针类型的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是在几个标准头文件中定义的,它不是像ifwhile这样的关键字,您需要包含一个定义它的头文件才能使用它。这个想法是,当指针指向地址零时,它被称为"空指针",这就是为什么它被称为NULL,当你想说"零地址"而不仅仅是"零数字"时,它会使用。

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

值为 0 的整数常量表达式或转换为类型 void * 的此类表达式称为空指针常量

后来

NULL(和其他标头(中定义为空指针常量;请参阅 7.19。

然后,在第 7.19 节中:

3 宏是

它扩展到实现定义的空指针常量;和

偏移量(类型成员指示符(

扩展到...

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

while循环可以像这样运行:

while(1) //This will run forever.
while(true) //This will run forever.

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

最新更新