重要的是要记住'\0'并不是真正的“字符串”,而是指向str(字符串的一部分)存储位置的内存位置的指针。
接下来,我们必须了解编译器如何看待所有这些项目。 让我们看看它们的类型:
'\0'是str类型(字面意思是“指向void *的指针”)
'\0'是一个空指针常量(至少在我的系统上是str)
'\0'是一个字符常量(它实际上是str类型,但是不用担心;它通常在需要void *值的上下文中使用)
看到str和void *中的'\0'? 这告诉编译器它们是指针类型(这是一种奇特的说法,这种类型的变量不保存该值,它们只是指向该值)。 因此,当编译器看到char *str时,它知道您可能会要求做类似*str或str[0]的事情(两者都做同样的事情)。 我们稍后再讲。
您会看到,当您在C程序中编写'\0'时,编译器会知道一个名为“ str”的变量存储在一个内存位置,例如0x0001。 它生成的代码进入0x0001并获取值。 这样,如果你做类似的事情
str + 1
然后,编译器将生成类似于以下内容的代码:
fetch the value from where str is stored (0x0001)
add 1 to that value
我确定你知道这件事。 所以现在很明显这行说了什么:
str == NULL
由于'\0'是空指针常量,因此该行测试str是否是空指针(即,不指向任何内容的指针)。
因此,编译器通常会生成如下代码:
fetch the value from where str is stored
check if that value is 0
现在请记住,如果您愿意,我们告诉编译器'\0'实际上是指针类型。 所以我们可以这样写:
*str
这使得编译器生成以下代码:
fetch the value from where str is stored
now use that value as a memory address and fetch what is stored there
因此,如果str保持0x0200,那么我们将从内存地址0x0200获得该值。 请注意,编译器实际上并不关心字符串是否确实存储在此。
(我假设您知道'\0'与str是相同的。它可以更容易地解释正在发生的事情。)
那呢?
*str == '\0'
因此,该行实际上是:
*str == (char) 0
这使得编译器生成以下代码:
fetch the value from where str is stored
now use that value like a memory address and fetch the char that is stored there
check if the value of that fetched char is 0
总结一下:
编写'\0'会告诉您指针str是否没有指向任何对象。
编写'\0'可以告诉您指针str是否指向空字符串(实际上,指向持有零的内存位置)。
(根据定义,“字符串”是“由第一个空字符终止并包括第一个空字符的连续字符序列,因此,如果字符串的第一个字符为'\0',则该字符串为空字符串。)