размер массива в с - PullRequest
       2

размер массива в с

18 голосов
/ 25 сентября 2011

простой вопрос, который меня беспокоит. Скажем, у меня есть массив, определенный в main, например, int arr[5]. Теперь, если я все еще в main и я установил int i = sizeof(arr)/sizeof(arr[0]), тогда для меня установлено значение 5, но если я передаю массив в качестве параметра функции и выполняю точно такие же вычисления в этой функции, я получаю другое число. Это почему? Сначала я подумал, потому что в функции arr это указатель, но, насколько я знаю, arr тоже указатель внутри main!

Кроме того, если я делаю что-то очень похожее, только динамически инициализирую массив, получаю странные результаты:

int *arr = (int*) malloc(sizeof(int) * 5);
int length = sizeof(*arr) / sizeof(arr[0]);
printf("%d\n",length);

Здесь вывод 1. Есть идеи почему? Заранее спасибо!

Ответы [ 6 ]

22 голосов
/ 25 сентября 2011
Массивы

C нигде не хранят свои собственные размеры, поэтому sizeof работает только так, как вы ожидаете, если размер известен во время компиляции.malloc() обрабатывается компилятором как любая другая функция, поэтому sizeof не может сказать, что arr указывает на первый элемент массива, не говоря уже о его размере.Если вам нужно знать размер массива, вам нужно явно передать его в вашу функцию, либо в качестве отдельного аргумента, либо с помощью структуры, содержащей указатель на ваш массив и его размер.

6 голосов
/ 25 сентября 2011

Это потому, что arr теперь является указателем и может указывать на одно целое число или массив из 1000 int, которые функция просто не знает.Вам нужно будет передать размер массива в функцию.

В main arr объявлен как int [5], и поэтому размер может быть вычислен компилятором.

5 голосов
/ 25 сентября 2011

Я не понял первый вопрос (напишите, пожалуйста, некоторый код), но для второго:

sizeof(*arr) ;   // is sizeof(int) as arr is of type "int *"
sizeof(arr[0]) ; // is sizeof(int), as arr[0] is the first
                 //     item of an array of int

Фактически, *arr и arr[0] означают абсолютно то же самое,сказал по-другому.Фактически, допустим, что n является индексом: *(arr + n) - это то же самое, что arr[n].

4 голосов
/ 25 сентября 2011

Насколько я знаю, arr - тоже указатель внутри main!

Это ошибка.В main, где вы определили int arr[5], arr - это массив, а не указатель.Его размер равен размеру массива, поэтому 5*sizeof(int).Когда вы передали его как параметр функции, этот параметр имел тип int*, поэтому внутри функции вы брали размер int*, а не int[5].

Здесьвывод равен 1. Есть идеи, почему?

На этот раз arr действительно является указателем, поскольку вы объявили его int *arr.Но в любом случае, int *arr или int a[5], *arr и arr[0] означают одно и то же: первый элемент.Так что, конечно, они имеют одинаковый размер, и sizeof(*arr) / sizeof(arr[0]) равно 1.

3 голосов
/ 25 сентября 2011

Вы должны понимать разницу между статическими и динамическими массивами.Статические массивы являются типами типа int, float, double и т. Д. Они различны.Четный

int a[10];

имеет тип, отличный от

int b[11];

Во время компиляции число элементов в статических массивах известно, а оператор sizeof возвращает количество байтов, которые они занимают.

С указателями, которые были инициализированы, либо для указания на некоторую переменную, либо на выделенную память, во время выполнения будет очевидно, куда они указывают, и компилятор не может определить, что будетразмер этого массива в будущем.Поэтому указатель sizeof дает 4 (или 8 в 64-битных системах, например).

Обратите внимание, что оператор sizeof работает во время компиляции, а не во время выполнения.

Если вам нужно узнать размер выделенной памяти (через malloc), у вас нет выбора, кроме как сохранить размер массива в другой переменной, например, сразу после того, как вы сделали malloc.

3 голосов
/ 25 сентября 2011

Это из-за разницы между массивом известного размера и указателем на массив неизвестного размера.sizeof выполняется во время компиляции, и компилятор не может заранее определить размер динамически создаваемой области памяти.

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