Из стандарта языка C (черновик n1256 ):
6.3.2.1 L-значения, массивы и обозначения функций
...
3 За исключением случаев, когда это операнд оператора sizeof
или унарный оператор &
или
строковый литерал, используемый для инициализации массива, выражение, которое имеет тип ‘‘ array of type ’’
преобразуется в выражение с указателем типа 101 ‘на тип ’, которое указывает на начальный элемент
объект массива и не является lvalue. Если объект массива имеет класс хранения регистров,
поведение не определено.
Запомните этот абзац, поскольку один из самых больших источников изжоги в C-программировании - это то, как C обрабатывает выражения массива.
Когда вы вызываете doStuff(afm1);
, выражение afm1
неявно преобразуется из типа "массив из 9 элементов int
" в "указатель на int
", и значение выражения такое же, как &afm1[0]
, Так что doStuff
получает значение указателя, а не массив.
В контексте объявления параметров функции T a[]
и T a[N]
оба интерпретируются как T *a
:
6.7.5.3 Объявление функций (включая прототипы)
...
7 Объявление параметра в виде массива type ’должно быть скорректировано с учетом‘ ‘квалифицированного указателя на
type ’’, где квалификаторы типа (если таковые имеются) указаны в [
и ]
вывод типа массива. Если ключевое слово static
также появляется в пределах [
и ]
вывод типа массива, затем для каждого вызова функции значение соответствующего
фактический аргумент должен обеспечивать доступ к первому элементу массива с как минимум
элементы, как указано в выражении размера.
Поскольку doStuff
получает значение указателя , а не массив, трюк sizeof
не работает. В общем, вы должны явно указать функции, какой размер массива вы ей передаете; вы не можете определить это по самому значению указателя.
Итак, когда вы звоните doStuff
из main
, вам нужно будет сделать что-то вроде
doStuff(afm1, sizeof afm1/sizeof *afm1);
...
int doStuff(int *afm, size_t afmsize)
{
...
}