字符串终止符’\ 0’如何与整数常量0具有相同的值?
我有以下代码 –
#include #define LENGTH 5 int main(){ char* ch[LENGTH] = {"Zero", "One", "Two", "Three", "Four"}; char* pc; char** ppc; for(int i=0; i<LENGTH; i++){ ppc = ch+i; pc = *ppc; while(*pc != 0){ printf("%c ", *pc); pc = pc +1; } printf("\n"); } return 0; }
它是使用字符串的多个间接的示例。
输出是
Z ero O ne T wo T hree F our
这里使用while()
循环而不是*pc != '\0'
,使用*pc != 0
。
但这两种方法都给出了相同的输出。 为什么会这样?
换行符\n
,制表符\t
等具有自己的转义序列字符,但实际上没有一个用于空终止符。
因此,代表空终止符的行业事实上的标准方法是写入值为零的八进制转义序列 。 八进制转义序列定义为\
后跟一个数字。 所以\0
只表示零,八进制表示。 由于这看起来类似于其他字符转义序列,因此它已成为表示空终止符的事实上的标准方式。
这就是为什么十进制0
工作得很好,这只是写零值的另一种方式。 如果你想要模糊,你也可以写\x0
。
char
实际上只不过是一个小整数,因此可以隐式转换为int
。 此外,字符文字(例如'A'
)实际上由编译器表示为int
值(例如,文字字符'A'
由ASCII编码中的int
值65
表示)。
C语言允许使用转义插入任意整数(可以放入char
)。 有两种方法可以使用八进制数或使用hex来转义此类任意值。 例如,A的ASCII值为65
,可以表示为'A'
,八进制的'\101'
,hex的'\x41'
或“纯65
。
有了这些信息,应该很容易看到字符文字'\0'
是整数0
的八进制表示。 也就是说, '\0' == 0
。
您可以通过打印轻松validation:
printf("'\\0' = %d\n", '\0');
我提到编译器将所有字符文字视为int
值,但也提到使用转义八进制或hex数字的任意数字需要适合char
。 这似乎是一个矛盾,但事实并非如此。 字符值必须符合char
,但编译器在解析代码时会在内部将其转换为int
。
0
和'\0'
完全相同,在C中,都是int
类型。 这是由C标准修复的,与您平台上的字符编码无关。 换句话说,它们完全没有区别。 (在C ++中, '\0'
的类型是一个char
。)
所以while(*pc != 0)
, while(*pc != '\0')
,而while(*pc)
就此而言都是一样的。
(就个人而言,我发现最后一个给出最清楚的,但有些人喜欢在使用C风格的字符串时使用'\0'
符号。)
添加到现有答案,查看哨兵 ,引用C11
,章节§5.2.1
在字符常量或字符串文字中,执行字符集的成员应由源字符集的相应成员或由反斜杠
\
后跟一个或多个字符组成的转义序列表示。 所有位都设置为0的字节,称为空字符,应存在于基本执行字符集中; 它用于终止字符串。
从章节§6.4.4.4/ P12开始,
示例1构造
'\0'
通常用于表示空字符。
因此,常数\0
是满足上述属性的常数。 这是一个八进制转义序列 。
现在,关于价值,引用§6.4.4.4/ P5,( 强调我的 )
八进制转义序列中反斜杠后面的八进制数字被视为构造整数字符常量的单个字符或宽字符常量的单个宽字符的一部分。 如此形成的八进制整数的数值指定所需字符或宽字符的值。
因此,对于八进制转义序列'\0'
,该值为0
(嗯,两者都是八进制,如§6.4.4.1和十进制中所述)。