Подтвердить что ты не робот

Почему C-Array имеет неправильное значение sizeof() при передаче функции?

Полный пример:

#include <stdio.h>

void test(int arr[]) {
    int arrSize = (int)(sizeof(arr) / sizeof(arr[0]));
    printf("%d\n", arrSize); // 2 (wrong?!)
}

int main (int argc, const char * argv[]) {
    int point[3] = {50, 30, 12};

    int arrSize = (int)(sizeof(point) / sizeof(point[0]));
    printf("%d\n", arrSize); // 3 (correct :-) )

    test(point);

    return 0;
}

Прежде чем передать его функции, sizeof дает мне правильное значение. Выполнение точно такой же вещи в одном и том же массиве в функции дает странные результаты. Там один элемент отсутствует. Почему?

4b9b3361

Ответ 1

Когда вы передаете массив в функцию в C, массив распадается на указатель на свой первый элемент. Когда вы используете sizeof для параметра, вы берете размер указателя, а не самого массива.

Если вам нужна функция, чтобы знать размер массива, вы должны передать ее как отдельный параметр:

void test(int arr[], size_t elems) {
   /* ... */
}

int main(int argc, const char * argv[]) {
   int point[3] = {50, 30, 12};
   /* ... */
   test(point, sizeof(point)/sizeof(point[0]));
   /* ... */
}

Также обратите внимание, что по той же причине (с помощью sizeof указателя) трюк sizeof(point)/sizeof(point[0]) не работает для динамически распределенного массива, а только массив, выделенный в стеке.

Ответ 2

Поскольку массив разложил на указатель, переданный как аргумент функции, поэтому sizeof дает вам 4 и 8 для 32- и 64-разрядных платформ соответственно.

Ответ 3

Также важно понять, что sizeof оценивается в время компиляции. Поскольку в этом случае нет смысла ожидать различного вывода в test() в зависимости от того, что было передано. Расчет sizeof выполнялся при компиляции функции.

Ответ 5

В C, С++ и Objective-C функции не могут иметь параметры массива. Они могут иметь параметры, которые выглядят как параметры массива, но они не. В вашем примере

void test(int arr[])

компилятор видит "есть параметр, который выглядит как массив int", и он заменяет этот параметр "указателем на int". Таким образом, функция, которую вы написали, абсолютно, на сто процентов, идентична

void test (int* arr)

Следовательно, внутри функции sizeof (arr) вы получите размер "указателя на int".

Ответ 6

Поскольку sizeof() НЕ говорит вам размер массива в C. Он делает что-то совершенно другое.

sizeof Ссылка на С++