我坚持使用\ 0的某些功能。
我知道\ 0是一个空字符,它是一个表示形式是字符串的术语。
a2
当我尝试打印“ abcdef \ 0abcdefg \ 0”时,C只打印字符串“ abcdef”和“ 6”,而不是总计“ 13”的“ abcdef”和“ abcdefg”。为什么发生这种情况?
答案 0 :(得分:0)
这里
j = printf("abcdef\0abcdefg\0"); /* printf stops printing once \0 encounters hence it prints abcdef */
printf()
从字符串常量"abcdef\0abcdefg\0"
的基地址开始打印,即从a
开始打印,直到遇到第一个\0
字符。因此它打印abcdef
。
-----------------------------------------------------------------
| a | b | c | d | e | f | \0 | a | b | c | d | e | f | f | g | \0 |
-----------------------------------------------------------------
0x100 0x101 ...............| 0x100 - assume this as base address of the string literal
| |
starts printing when printf sees
from 0x100 memory first \0
location it stops the printing & returns.
然后printf()
返回可打印字符数,即6
。
printf("%d", j); /* prints 6 */
在printf的手册页中
返回值
成功返回后,这些函数将返回 打印的字符(不包括空字节,用于结束输出 至 字符串)。
答案 1 :(得分:0)
C中的字符串是一个字符序列,后跟NUL字符'\0'
。没有单独的“长度”字段。
当字符串以文字形式显示时,例如"hello"
,实际上存储在内存中的是:
'h', 'e', 'l', 'l', 'o', '\0'
因此,您可以看到,如果字符串本身包含'\0'
,那么就任何C标准库函数而言,它就是字符串的结尾。
一旦printf
看到字符串中的第一个'\0'
,它将停止打印并返回,因为那是格式字符串的结尾。 printf
无法知道'\0'
之后还有另一个字符串。在那之后,也许有-或者也许在内存中只是随机的其他程序数据。无法分辨出差异。
如果要实际打印'\0'
字符,则需要采用其他方法来跟踪字符串的“实际”长度,并使用接受该长度作为参数的函数。另外,您可以在格式化过程中通过在格式字符串中指定'\0'
并传递%c
作为字符值来添加0
字符。
答案 2 :(得分:0)
"abcdef\0abcdefg\0"
(字符串文字)实际上是static
,const
(出于各种目的)char
数组,因此它具有与编译器相关的大小维护:
#include <stdio.h>
#define S "abcdef\0abcdefg\0"
//^string literals implicitly add a(nother) hidden \0 at the end
int main()
{
printf("%zu\n", sizeof(S)); //prints 16
}
但是数组在C中被特殊对待,并将它们作为参数传递给函数,或者几乎所有运算符都将其转换为指向其第一个元素的指针。
指针没有关联的大小。
当您将char const*
传递给函数(例如printf
)时,该函数仅接收一个数字-第一个元素的地址。
C中的printf
和大多数字符串函数获取大小的方法是对字符进行计数,直到第一个'\0'
。
如果您将指针传递到char
数组的第一个元素中,该数组的第一个元素具有显式嵌入的零,则对于直到第一个'\0'
为止一直计数的函数,字符串实际上在第一个结尾'\0'
。