sizeof('\0') null 终止符作为文字是四个字节,但为什么在字符串中它只需要一个字节?

sizeof('\0') null terminator as literal is four bytes but how come in string of characters it takes only one byte?

提问人:Mysterious Jack 提问时间:3/17/2023 更新时间:3/17/2023 访问量:127

问:

在 c '\0' 中,作为文字的 null 终止符需要 4 个字节(因为它内部只是零),但为什么在字符数组或字符串中使用时只需要 1 个字节?这个编译器是魔法吗?

程序员在使用动态内存分配来处理空终止符大小时是否需要特别小心?下面的程序可以吗?

#include<stdio.h>
#include<stdlib.h>

int main()
{
   printf("size of null-termination: %lu\n", sizeof('\0')); //outputs 4 bytes
   printf("size of 0: %lu\n", sizeof(0)); // outputs 4 bytes

   char *message = malloc(10);
   message[0] = 'A';
   message[1] = 'B';
   message[2] = 'C';
   message[3] = '\0'; // takes 1-byte in below memory layout(attached image)

   message[4] = 'a';
   message[5] = 'b';
   message[6] = 'c';
   message[7] = '\0'; // takes 1-byte in below memory layout(attached image)

   message[8] = 'X';
   message[9] = 'Y';

   printf("\n");
   return 0;
}

enter image description here

malloc c-strings 大小以 null 结尾

评论

0赞 Ian Abbott 3/17/2023
普通(非宽)字符常量具有 type ,而不是 ,因此这就是字符常量大小大于预期的原因。intchar
1赞 Ian Abbott 3/17/2023
sizeof生成 类型的值。对应的 printf 格式说明符是 ,而不是 。size_t%zu%lu
0赞 Jeremy Friesner 3/17/2023
printf("%zu\n", sizeof(char('\0')));打印“1”
0赞 Jabberwocky 3/17/2023
message[3]是单个字节,因此它的大小为 1。类型是和不是(我很奇怪,但就是这样),在您的平台上是 4。'x'intcharsizeof(int)
0赞 Mysterious Jack 3/17/2023
@JeremyFriesner即使使用“%zu”,它也会打印 4。感谢您的更正 Ian Abbot

答:

6赞 Vlad from Moscow 3/17/2023 #1

在 C 中,与 C++ 相反的是一个整数字符常量,其类型为 。'\0'int

在字符串文本中,此类转义序列存储为一个字符。

来自 C 标准(6.4.4.4 字符常量)

10 整数字符常量的类型为 int。整数的值 字符常量,包含映射到 单字节执行字符是 解释为整数的映射字符的表示形式

和(6.4.5 字符串文字)

6 在转换阶段 7 中,值为零的字节或代码被附加到 由字符串文本生成的每个多字节字符序列 或文字.78) 然后使用多字节字符序列 初始化一个静态存储持续时间和长度的数组 足以包含序列。对于字符串文字, 数组元素的类型为 char,并使用 多字节字符序列的单个字节

评论

0赞 Eric Postpischil 3/17/2023
Re “在字符串文字中,此类转义序列存储为一个字符”:在字符串文字中,空终止符只是一个字符。字符串文字的源代码中的“\”是一个转义字符:它转义了通常的字符解释,引入了另一种解释。其中,“\”是转义字符,“\a”是转义序列。生成的字符(警报字符)只是一个字符。"\a"