размер массива указателей - PullRequest
2 голосов
/ 20 декабря 2011

У меня есть сомнения относительно размера оператора

Код 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, а 2-й код o / p равен 4, хотя обе точки указывают на массив одинакового размера?

Ответы [ 5 ]

8 голосов
/ 20 декабря 2011

Вывод следующей программы даст вам некоторые подсказки и понимание размера типа и указателя на тип.

#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     |
|_____________________|
5 голосов
/ 20 декабря 2011

По сути, у вас есть массив указателей.Когда вы сделали *p, вы разыменовали указатель на первый элемент массива.Следовательно, тип будет int.sizeof(int*) на вашем компьютере просто равно 4.

Редактировать (уточнение):

Фрагмент кода 1, вы получаете размер массива.

Кодфрагмент 2, вы получаете размер типа, на который указывает первый элемент массива указателей.

2 голосов
/ 21 декабря 2011

В первом коде:

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 дает размер объекта массива, а не размер указателя)
  • Когда этооперанд унарного & (&arr возвращает адрес всего объекта массива, а не адрес его первого элемента; одно и то же место в памяти, разные типы)
  • Когда это строковый литерал в инициализаторе, используемый дляинициализировать объект массива (int arr[6] = "hello"; не преобразует "hello" в указатель, он копирует массив).

Настоятельно рекомендуется прочитать: раздел 6 comp.lang.cFAQ .

2 голосов
/ 20 декабря 2011

проверьте этот код:

в этом коде p указывает на массив указателей, следовательно, o / p равно 40

В вашем случае это массив указателей, поэтому o / p4

#include<stdio.h>
int main()
{
       int (*p)[10];
       printf("%d",sizeof(*p));   //output -- 40
       return 0;
}
0 голосов
/ 20 декабря 2011

Посмотрите в своем первом фрагменте кода p это массив, размер которого составляет 40 байт. Теперь получается, что 40 байт прост, Array p содержит 10 членов, и каждый элемент имеет размер 4 байта

   10*4=40

Во втором коде фрагмент p является ничем иным, как его массив указателей означает, что каждый член этого массива является указателем на значение типа int. Теперь * p обозначает значение в первом нижнем индексе массива, и это значение является не чем иным, как адресом, равным 4байт.

Надеемся, что все будет ясно для вас.

...