为什么sizeof(* pointer)给出的输出为1?

时间:2019-11-08 00:06:53

标签: c arrays string pointers

#include <stdio.h>
int main()
{
    char *str1 = "Abcde";
    char str2[] = "Abcde";

    printf("sizeof(str1) = %d, sizeof(str2) = %d sizeof(*str1) = %d",
        sizeof(str1), sizeof(str2),sizeof(*str1));

    return 0;
}

以上代码给出了sizeof(*str1) =1的输出。有人可以解释为什么我期望它在取消引用时成为sizeof("Abcde")

4 个答案:

答案 0 :(得分:2)

sizeof(*str1)之所以是1,因为:

  1. str1char *

  2. *str1char

  3. 根据定义,char的大小为1

"Abcde"分配给char *后,您将失去该原始字符串的所有上下文,包括其大小。

答案 1 :(得分:2)

其他答案正确地说明了sizeof (*str) == 1的原因,但是它们并不能解决您可以理解的困惑。

C数组在某种意义上是二等公民。数组对象是实际对象,就像任何其他类型的对象(整数,结构等)一样,但是该语言提供的操作很少,可以直接对数组进行操作。

相反,数组对象通常通过指向其元素的指针进行操作。

在您的示例中,您有:

char *str1 = "Abcde";

字符串文字"Abcde"对应于类型char[6]的匿名数组对象(字符串的长度为5,结尾的'\0'空字符为1)。因此sizeof "Abcde" == 6

但是str1不是指向该数组对象的指针;它只是指向其初始元素的指针,该初始元素包含字符'A'。如果要访问数组的其他元素(字符'b''c'等),则需要执行 pointer算术来使指针通过数组对象的元素。

所以最初是*str1 == 'A',但是在++str1之后是`* str1 =='b'。

如果要打印字符串的值,可以执行以下操作:

printf("%s\n", str1);

printf函数将在内部执行前进到字符串字符所需的指针算法。

这就是sizeof (*str) == 1的原因。它仅指向数组对象的单个元素。我们可以使用它来访问其他元素,但是指针值本身不包含有关数组大小的任何信息。 (这就是终止'\0'的作用,因此我们无需事先知道字符串的大小就可以识别字符串的结尾。)

请注意,您可以具有指向整个数组对象的指针:

char (*array_ptr)[6] = &"Abcde";

sizeof *array_ptr == 6 -但这没有您预期的有用。 array_ptr只能指向一个由6个元素组成的数组,并且由于printfstrlen之类的函数需要char*指针,因此您不能直接使用{{ 1}}。 (在处理多维数组时,确实会显示数组对象的指针-数组数组。)

与整个数组对象相反,指向数组元素的指针更加灵活,标准库广泛使用它们。缺点是您必须自己跟踪数组的大小,例如通过将其作为额外的参数传递或使用诸如array_ptr之类的前哨值来标记数组的结尾。

答案 2 :(得分:1)

因为*str1char

char是一个字节。

一个字节的大小为一个。

答案 3 :(得分:0)

sizeof有两种语法形式:

  • sizeof (TYPE),其中TYPE是一种类型(例如intchar等)
  • sizeof expr,其中expr是任何表达式(例如1*ptr等)

请注意,第二种形式中没有()!无论如何,TYPEexpr都不会被评估(正如标准所说:only for its size

注意:存在第三种(隐藏的)形式:

  • sizeof object;对象是一些标识符

在以下情况下:

char buff[123];
size_t sz = sizeof buff;

sz将是123,因此buff不会被提升/降级为指针。

注意:sizeof运算符的优先级很高(请检查表!),因此

sz = sizeof 1+2;

sz将等于sizeof(int) + 2

在您的情况下,*str将是一个字符,其值为'A':其大小将为一个:字符的大小。

仅此而已。