Разница между передачей массива и указателя массива в функцию в 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 элементов.