Во-первых, несколько стандартных :
6.7.5.3 Деклараторы функций (включая прототипы)
...
7 Объявление параметра как '' массив типа '' должно быть скорректировано как '' квалифицированный указатель на
тип '', где квалификаторы типа (если есть) являются теми, которые указаны внутри [
и ]
производного типа массива. Если ключевое слово static
также появляется внутри [
и ]
в производном типе массива, то для каждого вызова функции значение соответствующего фактического аргумента должно обеспечивать доступ к первому элементу массива с по крайней мере таким количеством элементов, как указано размером. выражение.
Короче говоря, любой параметр функции, объявленный как T a[]
или T a[N]
, обрабатывается так, как если бы он был объявлен T *a
.
Итак, почему параметры массива обрабатываются так, как будто они были объявлены как указатели? Вот почему:
6.3.2.1 Значения L, массивы и указатели функций
...
3 За исключением случаев, когда это операнд sizeof
оператора или унарный &
оператор, или строковый литерал, используемый для инициализации массива, выражение, имеющее тип "массив типа " 'преобразуется в выражение с типом' 'указатель на тип ' ', которое указывает на начальный элемент объекта массива и не является lvalue. Если объект массива имеет класс хранения регистров, поведение не определено.
Учитывая следующий код:
int main(void)
{
int arr[10];
foo(arr);
...
}
При вызове foo
выражение массива arr
не является операндом для sizeof
или &
, поэтому его тип неявно преобразуется из «10-элементного массива int
» в «указатель на 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):
Когда я разбираю основную функцию в .exe обеих вызывающих версий двоичного файла в IDA, я получаю точно такой же код сборки, как показано ниже:
Таким образом, нет никакой разницы между двумя версиями этого вызова, по крайней мере, компилятор угрожает им одинаково.
источник