Ответ 1
Пока вы работаете только с одномерными массивами, вышеупомянутые объявления эквивалентны. Последнее, хотя
void f(int i, int a[static i])
имеет дополнительный эффект. Он эквивалентен предыдущим в терминах типов параметров, но также сообщает компилятору, что он может полагаться на параметр a
, указывающий на массив не менее i
элементов (которые можно использовать при оптимизации).
Вы также забываете еще одно новое объявление
void f(int i, int a[const])
Этот эффект действительно имеет эффект даже в случае одномерного массива. Это эквивалентно
void f(int i, int *const a)
хотя некоторые могут утверждать, что const-qualifications по функциональным параметрам бесполезны. Прежде чем было невозможно const-qualify указатель, параметр массива "распадается" при использовании синтаксиса []
для объявления.
*
(а также i
) между []
начинает действовать только тогда, когда он используется между второй (или большей) парой []
в объявлении многомерного массива. По сути, он так же, как и всегда: размер массива в объявлении параметра всегда имел значение только между второй или следующей парой []
. *
используется в объявлениях прототипов для параметров VLA, когда значение размера не указано явно. Например, вы можете объявить
void bar(int n, int m, int a[n][m]);
и компилятор будет знать, что a
является VLA, поскольку размеры не являются константами. Но если вы предпочитаете не указывать параметры в прототипах, как вы собираетесь сообщить компилятору, что a
является VLA? Это когда *
помогает
void bar(int, int, int a[*][*]);