【问题标题】:size of array of pointers指针数组的大小
【发布时间】:2011-12-20 07:39:58
【问题描述】:

我对 sizeof 运算符有疑问

代码 1:

int main()
{
    int p[10];
    printf("%d",sizeof(p));   //output -- 40
    return 0;
}

代码 2:

int main()
{
    int *p[10];
    printf("%d",sizeof(*p));   //output -- 4
    return 0;
}

在第一个代码中 p 指向一个整数数组。 在第二个代码中 p 指向一个指针数组。 我无法理解为什么第一个代码 o/p 是 40 而第二个代码 o/p 是 4 认为两者都指向相同大小的数组?

【问题讨论】:

  • 在第二个示例中(通常用于数组),*pp[0] 相同。所以sizeof(*p)sizeof(p[0])一样是指针的大小。

标签: c arrays sizeof


【解决方案1】:

以下程序的输出将为您提供一些关于类型大小和指向类型的指针的提示和理解。

#include <stdio.h>

int main(void)
{
    int p1[10];
    int *p2[10];
    int (*p3)[10];

    printf("sizeof(int)   = %d\n", (int)sizeof(int));
    printf("sizeof(int *) = %d\n", (int)sizeof(int *));
    printf("sizeof(p1)    = %d\n", (int)sizeof(p1));
    printf("sizeof(p2)    = %d\n", (int)sizeof(p2));
    printf("sizeof(p3)    = %d\n", (int)sizeof(p3));

    return 0;
}

int p[10];      => 10 consecutive memory blocks (each can store data of type int) are allocated and named as p

int *p[10];     => 10 consecutive memory blocks (each can store data of type int *) are allocated and named as p

int (*p)[10];   => p is a pointer to an array of 10 consecutive memory blocks (each can store data of type int) 

现在来回答你的问题:

>> in the first code p points to an array of ints.
>> in the second code p points to an array of pointers.

你是对的。代码中:2、要获取p指向的数组的大小,需要传入基地址

printf("%d", (int)sizeof(p));

而不是以下

printf("%d", (int)sizeof(*p));   //output -- 4

以下是等价的:

*p, *(p+0), *(0+p), p[0]

>> what's the difference between p[10] and 
>> (*p)[10]...they appear same to me...plz explain

以下是您另一个问题的答案:

int p[10];
 _________________________________________
|   0   |   1   |   2   |         |   9   |
| (int) | (int) | (int) |  ...    | (int) |
|_______|_______|_______|_________|_______|


int (*p)[10]
 _____________________
|                     |
| pointer to array of |
|     10 integers     |
|_____________________|

【讨论】:

  • p[10] 和 (*p)[10] 有什么区别...它们在我看来是一样的...请解释一下
  • 我已经更新了我之前的答案以包含您的上述问题。希望这会有所帮助。
  • 谢谢……我明白了……你不能修改 p(如果是 p[10])但可以修改(如果是 (*p)[10])。 ..eg.increment..
  • @AmolSharma 我很高兴。 OTOH,您可以在完成锻炼/学习后将正确的帖子标记为您问题的答案吗?
【解决方案2】:

基本上,您有一个指针数组。当您执行*p 时,您取消了指向数组第一个元素的指针。因此,类型将是 int。 sizeof(int*) 在你的机器上恰好是 4。

编辑(澄清):

代码 sn -p 1,你正在抓取数组的大小。

代码 sn-p 2,您正在获取指针数组的第一个元素所指向的类型的大小。

【讨论】:

  • 但是sizeof 没有取消引用任何东西。
  • OP 取消了对指针的引用。 sizeof(*p) 表示“p所指向的大小”
  • 问题是sizeof 运算符很特殊,不会取消引用它的参数:-)
  • 不会 *p 是被取消引用的对象,而 sizeof 会采用它的大小吗?我想我从来没有听说过 sizeof 不采用取消引用的参数
  • 这是正确的,在我的机器上(64 位)'sizeof(*p) == 4' 和 'sizeof(int) == 4' 但 'sizeof(int*) == 8 ´ 所以它产生 sizeof int 而不是 int 指针
【解决方案3】:

在第一个代码中:

int p[10];

p 不指向整数数组; p 一个整数数组。在声明中

printf("%d",sizeof(p));

应该是

printf("%d", (int)sizeof(p));

表达式 p 仍然引用数组对象,因此 sizeof(p) 产生数组对象的大小,在您的系统上恰好是 40 个字节 (10 * sizeof (int))。

第二个:

int *p[10];

同样,p 一个指针数组。但是在下面的语句中:

printf("%d", (int)sizeof(*p));

表达式p 被转换为指向数组第一个元素的指针(不是 指向整个数组)。取消引用该指针(使用一元 * 运算符)会给您一个 int* 对象,即数组的第一个元素。您系统上的int* 指针的大小恰好是4。(sizeof (int)sizeof (int*) 不一定相同;它们恰好在您的系统上。)

在 C 中,规则是任何数组类型的表达式(例如数组变量的名称)都会自动转换为指向数组第一个元素的指针——大多数时候。有三个例外:

  • 当它是 sizeof 的操作数时(sizeof arr 产生数组对象的大小,而不是指针的大小)
  • 当它是一元 &amp; 的操作数时(&amp;arr 产生整个数组对象的地址,而不是其第一个元素的地址;相同的内存位置,不同的类型)
  • 当它是用于初始化数组对象的初始化程序中的字符串文字时(int arr[6] = "hello"; 不会将 "hello" 转换为指针,它会复制数组)。

强烈推荐阅读:comp.lang.c FAQ 的第 6 节。

【讨论】:

    【解决方案4】:

    检查此代码:

    在此代码中,p 指向一个指针数组,因此 o/p 为 40

    在你的情况下,它是一个指针数组,所以 o/p 是 4

    #include<stdio.h>
    int main()
    {
           int (*p)[10];
           printf("%d",sizeof(*p));   //output -- 40
           return 0;
    }
    

    【讨论】:

      【解决方案5】:

      在第一个代码中 sizeof(Array) 将返回为该数组分配的总字节数。您可以通过

      获得正确的数组大小
      int size= sizeof(Array)/sizeof(Array[0]);
      

      在第二个代码中,它返回指针的大小。

      【讨论】:

        【解决方案6】:

        看看你的第一个代码 sn-p p 是一个大小为 40 字节的数组。现在它是 40 字节的很简单,数组 p 确实包含 10 个成员,每个成员的大小为 4 个字节

           10*4=40
        

        在第二个代码中,sn-p p 只不过是它的指针数组,这意味着这个数组的每个成员都是一个指向 int 值的指针。现在 *p 表示数组第一个下标的值,这个值只不过是一个地址是 4 个字节。

        希望你现在一切都清楚了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-01-02
          • 2014-06-17
          • 2017-11-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多