sizeof(string) 不包括“\”符号

sizeof(string) not including a "\" sign

我一直在研究 strlensizeof 的字符串(字符数组),但我不太明白一件事。 我有以下代码:

int main() {
    char str[]="gdb[=10=]eahr";
    printf("sizeof=%u\n",sizeof(str));
    printf("strlen=%u\n",strlen(str));
    return 0;
}

代码的输出是:

sizeof=9  
strlen=3

起初我很确定 2 个单独的字符 \ 后跟 0 实际上不会充当 NUL ([=18=]) 但我设法图它确实如此。 问题是我不知道为什么 sizeof 显示 9 而不是 10。 由于 sizeof 按数据类型计算使用的字节数,为什么它不计算 \ 的字节数?

在下面的例子中:

char str[]="abc";
printf("sizeof=%u\n",sizeof(str));

由于 NUL 值终止了数组,所以会打印出“4”,那么为什么 \ 不被计算在内呢?

为什么 char str[]="gdb[=10=]eahr"; 应该是 10 字节与 sizeof 运算符?它是 9 个字节,因为有 8 个字符串元素 + 尾随零 .

[=14=] 只有 1 个字符,而不是 2 个。\ 的目的是转义字符,因此您可能会看到其中的一些字符:\t\n , \

Strlen returns 3 因为你在位置 str[3].

处有 字符串终止符

\ 的单个序列作为 转义字符 并且不是字符串大小的一部分。如果你想在你的字符串中直接使用 \,你必须像 \ 一样按顺序写两次,那么这是 \ 可打印字符的单个 char

看来你已经有了答案:

At first I was pretty sure that 2 separate characters "\" followed by "0" wouldn't actually act as a NULL "[=11=]" but I managed to figure that it does.

序列 [=10=] 是字节 0 的八进制转义序列。因此,虽然代码中有两个字符表示它,但它在字符串中转换为单个字节。

所以你有7个字母字符,中间一个空字节,最后一个空字节。那是 9 个字节。

在字符或字符串常量中,\ 字符标记 转义序列的开始 ,用于表示没有符号的字符值在源字符集中。例如转义序列\n表示换行符,\b表示退格符,[=13=]表示零值字符(也是字符串终止符)等。

在字符串文字 "gdb[=14=]eahr" 中,转义序列 [=13=] 映射到单个 0 值字符; str 的实际内容是 {'g', 'd', 'b', 0, 'e', 'a', 'h', 'r', 0}

C 编译器将扫描文本字符串作为编译源代码的一部分,并且在扫描期间,任何特殊的字符转义序列都会变成单个字符。符号反斜杠 (\) 用于指示转义序列的开始。

转义序列有多种格式。最基本的是反斜杠后跟几个特殊字母之一。然后将这两个字符翻译成一个字符。其中一些是:

  • '\n'转为换行符(0x0A或十进制10)
  • '\t'转为制表符(0x09或十进制9)
  • '\r'变成回车return字符(0x0D或十进制13)
  • '\\'变成反斜杠字符(0x5C)

这个转义序列的想法在过去被使用过,这样当一行文本被打印到电传打字机或打印机或 CRT 终端时,程序员可以使用这些和其他特殊的命令代码字符来设置在哪里将打印下一个字符或使设备执行某些物理操作,例如按铃或将纸张送入下一行。

转义字符还允许您将双引号 (") 或单引号 (') 嵌入到文本字符串中,以便打印包含引号的文本。

除了上述反斜杠后跟字母的特殊序列之外,还有一种方法可以通过使用反斜杠后跟最多三个八进制数字(0 到 7)来指定任何字符。因此,您可以使用 '\n' 或使用 '\12' 指定换行符,其中 12 是十六进制值 A 或十进制值 10 的八进制表示形式。

然后引入了使用十六进制转义序列的功能,其中反斜杠后跟字母 x,后跟一个或多个十六进制数字。所以你可以用'\n'或'\12'或'\xa'写一个换行符。

另见 Escape sequences in C in Wikipedia