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

时间:2015-05-08 09:24:03

标签: c string pointers sizeof

#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

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

5 个答案:

答案 0 :(得分:10)

第1点

sizeof重新计算数据类型的 size ,而不是分配给变量的内存量。

如果你想衡量一个字符串长度,(即字符串中的元素数量),你有什么价值,你可以使用strlen()

第2点

不要对数据类型感到困惑。

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

第3点

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

答案 1 :(得分:3)

str是指向char的长度为6的指针数组。它的总大小是指针大小的6倍,在你的平台上可以得到48个。

答案 2 :(得分:3)

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

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

此外,[{1}}类型printf() size_t的正确方法是sizeof返回的%zu

答案 3 :(得分:2)

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

您应该使用%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 %zu\n", sizeof(str), sizeof(str[0]));
}

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

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

答案 4 :(得分:0)

声明为

的数组
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';

当你有一个指向字符串文字的指针数组时(如你原来的帖子中那样)你可能不会写

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

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

还有一个关于sizeof运营商的问题。根据C标准(6.5.3.4 sizeof和alignof运算符)

  

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

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

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

sizeof( array ) / sizeof( *array )