sizeof(char *) 和 sizeof(char) 有何不同?

How is sizeof(char *) and sizeof(char) different?

#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!

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

看来您使用的是 64 位系统,其中 sizeof (char *) 是 8。

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

此外,printf() 类型 size_t 的值的正确方法是 sizeof returns,即 %zu.

点 1

sizeof 返回数据类型的 size,而不是分配给变量的内存量。

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

点 2

不要混淆数据类型。

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

点 3

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

printf 格式说明符 %d 不适用于类型为 size_t.

的参数值 sizeof(str)sizeof(str[0])

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

您的代码还有更多问题:

  • main 的 return 类型必须指定为 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 %zu\n", sizeof(str), sizeof(str[0]));
}

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

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

添加 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) 在运算符 sizeof 中,它们不会隐式转换为指向其第一个字符的指针,它们被视为数组。

您可以按以下方式定义二维字符串数组

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

在这种情况下

sizeof( str[0] )

等于 6 并且

sizeof( str )

将等于 36,因为在这种情况下 strchar [6]

类型元素的数组

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

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

而当你有一个指向字符串文字的指针数组时(就像你原来的post)你可能不会写

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

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

还有一个关于 sizeof 运算符的。根据 C 标准(6.5.3.4 The sizeof and alignof operators)

2 The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

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

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

sizeof( array ) / sizeof( *array )