Получить длину массива по указателю - PullRequest
1 голос
/ 29 марта 2020
int narr[4] = {0};
int *pnarr = narr;
printf("size of pnarr:%d and *pnarr:%d\n", sizeof(pnarr), sizeof(*pnarr));

sizeof(pnarr) возвращает размер типа указателя. Но sizeof(*pnarr) возвращает размер типа int. Почему?

Указывает ли pnarr на первый элемент narr, поэтому я не могу получить длину массива на pnarr?

Как я могу получить длину массива по указателю ?

Вот код получения длины массива по указателю. Это правильно?

int arr_len(int *arr) {
    int len = 0;
    while (*arr)
    {
        arr++;
        len++;
    }
    return len;
}

Ответы [ 3 ]

2 голосов
/ 29 марта 2020

То, что вы получите, на самом деле и ожидается. С

int *pnarr;
sizeof (pnarr);

вы получаете размер указателя int*, то есть адреса (обычно 4 или 8 байт в зависимости от архитектуры вашей системы). Вы получите его по любому адресу, который вам назначен.


Функция arr_len (), которую вы разместили в вопросе, не найдет длину массива, потому что она ошибочно полагает, что последний элемент равен 0. Это обычно не соответствует действительности.

Это делается вместо этого с strings (массив символов), которые на самом деле являются символами, оканчивающимися на 0. Но в этом случае это стандарт, и вы уверены, что строка не будет содержать нулей в середине.


В заключение, если вам нужен общий размер в байтах массива, вы можете получить его из исходного имени массива с помощью

sizeof(narr)

Если вам нужно количество элементов массива, просто используйте

sizeof(narr)/sizeof(narr [0])

Так что вы не можете сделать это с указателем, но вам нужен исходный массив "reference" .

0 голосов
/ 29 марта 2020

Тип выражения *pnarr равен int, поэтому sizeof *pnarr == sizeof (int). Тип выражения narr равен int [4], поэтому sizeof narr == sizeof (int [4]).

В большинстве случаев выражение narr преобразуется («распад») из типа int [4] в тип int * - исключения возникают, когда выражение является операндом операторов sizeof или унарных &, или когда массив является строковым литералом, который используется для инициализации массива символьного типа в объявлении.

Вы не можете получить размер массива из указателя на первый элемент - вы должны отслеживать это вручную.

0 голосов
/ 29 марта 2020

Это ожидаемое поведение. pnarr - указатель, поэтому sizeof () должен возвращать размер указателя int. Разыменованный pnarr является int, поэтому sizeof () должен возвращать размер int. Я предлагаю вам сначала прочитать документацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...