Разница между передачей массива и указателя массива в функцию в C
в чем разница между двумя функциями в C?
void f1(double a[]) {
//...
}
void f2(double *a) {
//...
}
если бы я должен был вызвать функции на существенно длинном массиве, будут ли эти две функции вести себя по-разному, будут ли они занимать больше места в стеке?
3 ответа:
во-первых, некоторые standardese:
6.7.5.3 деклараторы функций (включая прототипы)
...
7 объявление параметра как ‘массив тип "должен быть настроен на" квалифицированный указатель тип’, где квалификаторы типов (если таковые имеются) указаны в[
и]
из вывод типа массива. Если ключевое словоstatic
также появляется в пределах[
и]
of этот вывод типа массива, то для каждого вызова функции, значение соответствующего фактический аргумент должен предоставить доступ к первому элементу массива, по крайней мере элементы, указанные в выражении размера.короче говоря, любой параметр функции объявлен как
T a[]
илиT a[N]
относятся как будто было объявленоT *a
.Итак, почему параметры массива обрабатываются так, как если бы они были объявлены как указатели? Это место почему:
6.3.2.1 значения, массивы и указатели функций
...
3 за исключением случаев, когда операндsizeof
оператор или унарный&
оператор, или a строковый литерал, используемый для инициализации массива, выражение, которое имеет тип " массив тип’ это преобразуется в выражение с типом " указатель на тип " это указывает на начальный элемент объект Array и не является левосторонним значением. Если объект массива присвоен класс регистра хранения, поведение не определено.учитывая следующий код:
int main(void) { int arr[10]; foo(arr); ... }
в вызове
foo
выражение массивarr
не является операндом ни того, ни другогоsizeof
или&
, поэтому его тип неявно преобразуется из "10-элемент массиваint
указатель" to " наint
" в соответствии с пунктом 6.2.3.1/3. Таким образом,foo
получит значение указателя, а не значение массива.из-за 6.7.5.3/7, Вы можете написать
foo
какvoid foo(int a[]) // or int a[10] { ... }
но это будет интерпретироваться как
void foo(int *a) { ... }
таким образом, эти две формы идентичны.
последнее предложение в 6.7.5.3 / 7 было введено с C99, и в основном означает, что если у вас есть объявление параметра, например
void foo(int a[static 10]) { ... }
фактический параметр, соответствующий
a
должен быть массив с по крайней мере 10 элементов.