Это своего рода асимметрия в синтаксисе языка Си. В C невозможно передать массив функции, поэтому, когда вы используете синтаксис массива в объявлении функции для одного из параметров, компилятор вместо этого читает его как указатель.
В C в большинстве случаев, когда вы используете массив в выражении, массив неявно преобразуется в указатель на его первый элемент, и это именно то, что происходит, например, при вызове функции. В следующем коде:
int bar[] = {1,2,3,4};
foo(bar);
массив преобразуется в указатель на первый элемент, и это то, что получает функция.
Однако это правило преобразования импликов применяется не всегда. Например, как вы обнаружили, оператор sizeof
работает с массивом, и даже оператор &
(address-of) работает с исходным массивом (т.е. sizeof(*&bar) == 4*sizeof(int)
).
Функция в C не может получить массив в качестве параметра, она может получить только указатель на первый элемент или указатель на массив ... или вы должны заключить массив в структуру.
Даже если вы поместите число в скобках в объявлении функции ...
void foo(int x[4])
{
...
}
это число полностью игнорируется компилятором ... это объявление для компилятора полностью эквивалентно
void foo(int *x)
{
...
}
и, например, даже вызов его при передаче массива с другим размером не вызовет никакой ошибки ...
int tooshort[] = {1,2,3};
foo(tooshort); /* Legal, even if probably wrong */
(на самом деле компилятор МОЖЕТ выдавать предупреждение, но код является совершенно допустимым C и должен приниматься, если компилятор следует стандарту)
Если вы считаете, что это правило для массивов в аргументах функции странное, тогда я согласен, но именно так определяется язык Си.