#arrays #c #function #pointers #sizeof
#массивы #c #функция #указатели #sizeof
Вопрос:
Когда я использую этот код в main()
функции, размер (или длина) массива вычисляется правильно:
#include <stdio.h>
int main(void)
{
int arr[] = {2, 5, 9, 8, 4, 5, 1, 2, 8, 5};
int length = sizeof(arr) / sizeof(arr[0]);
printf("The number of elements in the array is %dn", length);
return 0;
}
Выходной сигнал:
The number of elements in the array is 10
Но когда я делаю то же самое с помощью функции, то результат получается неправильным:
#include <stdio.h>
int sizeTeller(int array[]);
int main(void)
{
int arr[] = {2, 5, 9, 8, 4, 5, 1, 2, 8, 5};
printf("The number of elements in the array is %dn", sizeTeller(arr));
return 0;
}
int sizeTeller(int array[])
{
int len;
return (len = sizeof(array) / sizeof(array[0]));
}
Выходной сигнал:
The number of elements in the array is 2
Не могли бы вы, пожалуйста, объяснить мне, почему это так? Я предпочитаю сохранять все коды в функциях, поэтому я попробовал то же самое здесь, но результат пошел не так.
Ответ №1:
Это потому, что, как и во многих других случаях, когда массивы передаются в качестве аргумента функции, они распадаются до указателя на первый элемент массива. Следовательно, в вызываемой функции полученный тип параметра является указателем, а не массивом.
Итак, в случае
int sizeTeller(int array[])
{
int len;
return (len = sizeof(array) / sizeof(array[0]));
}
эквивалентно
int sizeTeller(int* array)
{
int len;
return (len = sizeof(array) / sizeof(array[0])); // sizeof (int *) / sizeof (int)
}
Решение: Если вам нужно передать массив в качестве аргумента функции и вам нужно знать его размер, вам нужно вычислить размер в вызывающем объекте и передать его в качестве другого аргумента вызываемой функции.
ПРИМЕЧАНИЕ:
Цитирование C11
, глава 6.3.2.1/P3
За исключением случаев, когда это операнд
sizeof
оператора,_Alignof
оператора или унарногоamp;
оператора, или строковый литерал, используемый для инициализации массива, выражение, имеющее тип ‘массив типа’, преобразуется в выражение с типом ‘указатель на тип’, который указывает на начальный элемент массиваобъект и не является значением lvalue . [….]
Комментарии:
1. означает ли это, что
sizeof(arr)
то, что находится вmain()
, вычисляет размер полного массива. Я имеюarr
в виду, что это также указатель на первый элемент массива, так почему же он не вернул размер указателя наint
, как это было бы сделано вsizeof(int*)
.2. @Neeraj-Kumar-Coder Нет, обратите внимание на часть «как и во многих других случаях», это не «всегда». Я немного расширю ответ, чтобы уточнить.
3. Я понял вашу точку зрения и понял причину неправильного вывода. Но просто объясните мне это, что
arr
если это указатель на первый элемент массива (как вmain()
функции), то почемуsizeof(arr)
не возвращается8 bytes
, что является размером указателя на int .4. Вы читали последнюю правку? В нем конкретно говорится, что, кроме сценариев,
sizeof
operator является одним из них.