字符数组的大小和字符指针的大小

20

我有一段 C 代码,但我不理解 sizeof(...) 函数的工作原理:

#include <stdio.h>

int main(){
   const char  firstname[] = "bobby";
   const char* lastname = "eraserhead";
   printf("%lu\n", sizeof(firstname) + sizeof(lastname));
   return 0;
}
在上面的代码中,firstname 的大小为 6,lastname 的大小为 8。
但是 "bobby" 是5个字符宽,"eraserhead" 是11个字符宽。我期望结果是16。
为什么对于字符数组和指向字符的指针 sizeof 表现不同?
有人能澄清一下吗?

6
sizeofstrlen()函数的结果类型都是size_t。在打印size_t值时应该使用%zu而不是%lu。如果你的编译器不支持%zu,则可以将size_t转换为已知类型,并使用该类型的适当格式进行打印。 - Keith Thompson
6个回答

26

firstname是一个带有尾随0终止符的char数组。lastname是一个指针。在64位系统上,指针宽度为8个字节。


显然,OP试图找出字符串的大小即串长度,并将它们相加,正如他所说的“为什么不是5+10=15?”是否真的可以通过使用‘sizeof’得到字符串长度,或者‘strlen()’更合适?你怎么看? - 0decimal0
2
@PHIfounder:在 C 中,字符串是由以 '\0' 字符结尾的一系列字符表示的,可以使用 strlen() 函数获取字符串的长度。这适用于“真实”的字符数组,也适用于指向后者的指针。在这种情况下,字符存储的方式和位置并不是最重要的。事实上,持有该字符串的变量不一定需要与字符串的长度相匹配。另一方面,如果有兴趣了解一个变量声明要使用的字节数量,则可以使用 sizeof 运算符。 - alk
2
存储字符串s(或由s指向的字符串)所需的字节数为strlen(s) + 1 - Keith Thompson

6

sizeof一个数组是整个数组的大小,在“bobby”的情况下,它有5个字符和一个尾随的\0,总共为6。

sizeof一个指针是指针的大小,在32位机器上通常为4字节,在64位机器上为8字节。


4

sizeof(...)函数的工作原理

sizeof()看起来像一个函数,但它不是一个函数。函数在运行时计算某些内容。

sizeof()会在编译时询问编译器分配给参数的内存大小。sizeof()不知道你实际运行时使用了多少内存。换句话说,你在示例中已经“硬编码”了printf参数。

为什么字符数组和指向字符的指针使用sizeof时表现不同?

指针所需的内存通常与数组不同。

通常情况下,分配给指针的内存量与其所指向的内容不同。


4

你的第一个数组的大小是bobby\0的大小。 \0 是终止字符,因此大小为6。

第二个大小是指针的大小,在64位系统中为8字节。它的大小不取决于分配字符串的长度。


3
firstname 是一个包含6个字符的数组,包括字符串末尾的终止符'\0'。因此,sizeof firstname 是6。 lastname 是一个指向char类型的指针,在你的系统上会有相应大小的指针。通常是4或8个字节。无论它指向什么(甚至指向空),lastname 的大小都将保持不变。

2

firstname[] 是以空字符结尾的,这会使长度加1。

sizeof(lastname) 给出的是指针的大小,而不是实际值的大小。


3
*lastname 是一个单一的 char 类型,因此 sizeof *lastname 的结果永远是1。 - caf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接