我看过this post。 但是当我尝试时:
printf("before null %c after null\n", 0); // (ASCII=0) != '\0' ??
而不是得到:
before null
我得到了:
before null after null
所以我的问题是: ASCII值0实际上等于' \ 0'?
答案 0 :(得分:5)
ASCII值0实际上是否等于
\0
?
是
字符串存储在内存中以及由printf()
等函数处理的差异非常重要。
"before null %c after null\n"
"before null \0 after null\n"
两者都存储在内存中,末尾有一个隐式\0
终止符。第二个在中间有一个明确的\0
字符的事实改变了事情。
printf()
将扫描字符串,直到“结束”,打印组件,因为它在C“结束”通常意味着直到第一个\0
/ nul 字符。
使用第一个变体,printf()
将字符复制到输出,直到它到达%c
指令,此时它会查看给函数的参数...它可能会发现你给了'\0'
,或者它可能会发现你给了'+'
- 无论哪种方式,它都会将其复制到输出中。然后它会继续将字符复制到输出中,寻找字符串的“结束”。
使用第二个变体,printf()
将开始将字符复制到输出,将找到“ the end ”(由\0
表示),并停止。
如果您使用snprintf()
,则结果/输出将包含以下内容:(同样,隐式\0
终止)
"before null \0 after null\n"
"before null "
如果您随后打印这两个,它们看起来相同,但内存内容会有所不同。
然而,printf()
的输出是终端(或文件)...... \0
会发生什么情况取决于您的终端仿真器......它可能根本就没有显示,可能是显示为空格,或者它可能有一个有趣的方框符号......
需要注意的重要一点是,这发生在运行时 - 而不是编译时。
答案 1 :(得分:3)
原因是printf
不是实际上用"Hello %s", "World"
替换"Hello World"
然后将它们打印出来。 相反,它会在每个字符 solo 的行中打印"Hello "
然后"World"
,按顺序
如果您曾尝试使用null
打印单个putchar()
字符,请注意它会打印一个空格,这就是printf
打印一个空格的原因空间也基于它。
请注意,它会在其他系统(例如Linux)上打印 nothing 。
printf实际工作方式的示例代码。
const char * x;
// while the current char != '\0'
while (*format)
{
// if the current char == '%'
if (*format == '%')
{
// increment the pointer so we can point to the next char and skip printing '%'
switch (*(++format)) // then switch that next char (specifier).
{
case 'c':
putchar(va_arg(args, char)); // if the argument is null, then it's putchar(0);
break;
case 's':
// regular operation of printing a string argument.
x = va_arg(args, const char*);
while (*x) putchar(*x++);
break;
}
// skips the format specifier so we don't print it (e.g 's', 'c'..)
*format++;
}
// else: isn't a format specfier.
else
// print the current char (pointer) of the original string
putchar(*format++); // increments it for the next operation.
}
va_end(args);
所以回到你的问题,它将打印每个字符,当涉及到 null 的参数0
时,putchar()
将放置空格或基于空格在你的系统上。
您可以说printf
参数不是与原始字符串确实有任何关系以终止它,他们彼此不认识。
就像当你printf("Hello %s, from SO!", "World");
时, "World"
实际上在\0
结束时终止,但它会自行终止,而不是其他, from SO!
。
是,0
为'\0'
。他们是同一个角色。
答案 2 :(得分:1)
printf
或{{1}时, %c
不会在0
格式说明符的字符位置终止printf格式字符串}。相反,'\0'
的终端输出通常是占位符(例如nul
等)
但是,您可以在字符串中插入space
,然后使用nul
格式说明符输出字符串,并查看实际上 decimal 0实际上是等效ASCII 字符的 %s
的ASCII值,并将在 nul-character 处终止字符串(请参阅:{{3 }}),例如
'\0'
示例使用/输出
#include <stdio.h>
#define FMT "before null %c after null\n"
int main (void) {
char buf[sizeof FMT * 2];
puts (FMT);
sprintf (buf, FMT, 0);
printf ("using 0 : '%s'", buf);
putchar ('\n');
sprintf (buf, FMT, '\0');
printf ("using \\0: '%s'", buf);
putchar ('\n');
return 0;
}