C语言 sizeof(char *) 和 sizeof(char) 有何不同?


#include<stdio.h>
main()
{
char *str[]= {"Frogs","do","not","die","they","croak"};
printf("%d %d %d",sizeof(str),sizeof(str[0]),sizeof(char));
}

输出为:

48 8 1

根据char的大小1字节,并且有六个字符变量,因此数组的总大小应6而不是48

1 点

sizeof重新运行数据类型的大小,而不是分配给变量的内存量。

对于它的价值,如果你想测量字符串的长度(即字符串中的元素数量),你可以使用strlen()

要点 2

不要与数据类型混淆。

  • str是一个指针数组。它包含6指针,因此sizeof将给出6 * sizeof(<pointer type>)在 64 位系统上6 * 848
  • str[0]是一个指针,因此sizeof str[0]等于在 64 位系统上8sizeof(char *)
  • C标准保证sizeof(char)等于1

要点 3

sizeof运算符返回一个size_t。您需要使用%zu格式说明符来便携可靠地打印它。

str是一个长度为 6 的指针数组,指向char。它的总大小是指针大小的 6 倍,在您的平台上有 48 个。

您似乎使用的是 64 位系统,其中sizeof (char *)为 8。

这解释了第一个值,因为sizeof str是对象str的大小,其类型为char *[6]。所以你得到的大小是48,当然是6 * 8。

此外,printf()size_t类型的值的正确方法是sizeof返回的内容,是使用%zu

printf格式说明符%d不适用于类型为size_t的参数值sizeof(str)sizeof(str[0])

您应该使用%zu或将参数转换为(int)

您的代码还有更多问题:

  • main的返回类型必须指定为int
  • str的类型应const char *str[]
  • 应向 printf 格式添加n,以确保在所有系统上正确刷新输出 ID。

这是一个改进的版本:

#include <stdio.h>
int main(void) {
const char *str[] = { "Frogs", "do", "not", "die", "they", "croak" };
printf("%zu %zun", sizeof(str), sizeof(str[0]));
}

它应该分别在 32 位和 64 位系统上输出24 448 8,在更奇特的系统上可能输出其他值。第一个数字是指向const char的 6 个指针的大小,第二个数字是单个此类指针的大小。

字符串本身的大小可以在编译时确定常量即时字符串和定义的数组,只能作为sizeof的直接参数。 在其他情况下,您必须使用strlen()来计算字符串长度(假设它们不包含嵌入式 NULL),并为最终''添加 1。

一个声明为

char *str[]={"Frogs","do","not","die","they","croak"};

具有类型char *[6]. 也就是说,它是指向字符的 6 个指针的光晕。因此,str[0]具有类型char *即它是一个指针。

因此

sizeof( str[0] )

相当于

sizeof( char * )

在您的系统中等于 8。

挨次

sizeof ( str )

相当于

6 * sizeof( char * )

等于 48。

考虑到在此初始值设定项列表中

char *str[]={"Frogs","do","not","die","they","croak"};

字符串文本隐式转换为指向其第一个字符的指针。

另一方面,如果你会写例如

sizeof( "Frogs" )

然后表达式将等于 6,因为 1) 字符串文字是包含终止零的字符数组和 2) 在运算符大小中,它们不会隐式转换为指向其第一个字符的指针,它们被视为数组。

您可以通过以下方式定义字符串的二维数组

char str[][6] = { "Frogs", "do", "not", "die", "they", "croak" };

在这种情况下

sizeof( str[0] )

将等于 6 并且

sizeof( str )

将等于 36,因为在本例中str是类型为char [6]的元素数组

请注意,在最后一种情况下,您可以通过以下方式更改数组的元素

str[0][0] = 'f';

而当你有一个指向字符串文字的指针数组时(如你的原始帖子),你可能不会写

str[0][0] = 'f';

因为字符串文本是不可变的。

还有一个关于sizeof运算符的信息。根据C标准(6.5.3.4运算符的大小和对齐)

2 sizeof 运算符产生其操作数的大小(以字节为单位), 可以是表达式或类型的括号名称。这 大小由操作数的类型确定。结果是一个 整数。如果操作数的类型是可变长度数组类型, 计算操作数;否则,不计算操作数,并且 结果是一个整数常量。

因此,应用于数组时,运算符会产生数组占用的字节数。它不会产生数组中的元素数。如果你想获取数组中元素的数量,你应该使用表达式

sizeof( array ) / sizeof( array[0] )

sizeof( array ) / sizeof( *array )

最新更新