Разница между передачей массива и указателя массива в функцию в C


в чем разница между двумя функциями в C?

void f1(double a[]) {
   //...
}

void f2(double *a) {
   //...
}

если бы я должен был вызвать функции на существенно длинном массиве, будут ли эти две функции вести себя по-разному, будут ли они занимать больше места в стеке?

3 92

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 элементов.

разница чисто синтаксическая. В C, когда нотация массива используется для параметра функции, она автоматически преобразуется в объявление указателя.

нет, нет никакой разницы между ними. Для тестирования я написал этот код C в компиляторе Dev C++(mingw):

#include <stdio.h>

void function(int* array) {
     int a =5;
}

void main() {  
     int array[]={2,4};
     function(array);
     getch();
}

когда я дизассемблировал главная