답변:
첫째, 몇 가지 표준 :
(원형 포함) 6.7.5.3 함수 선언자
...
'배열'과 같은 파라미터도 7a 선언 유형 '' '으로 규정 포인터'로 조정된다 입력 타입 한정자 (있는 경우) 그 지정된 ', 내[
및]
어레이 형의 유도. 키워드static
가 배열 유형 파생[
및 내부에도 표시되는 경우]
함수에 대한 각 호출에 대해 해당 실제 인수의 값은 크기에 지정된만큼의 요소가있는 배열의 첫 번째 요소에 대한 액세스를 제공해야합니다. 표현.
그래서, 짧은에, 어떤 함수 매개 변수는 다음과 같이 선언 T a[]
또는 T a[N]
처리 것처럼 그것을 선언했다 T *a
.
그렇다면 배열 매개 변수가 포인터로 선언 된 것처럼 처리되는 이유는 무엇입니까? 그 이유는 다음과 같습니다.
6.3.2.1 Lvalues, 배열 및 기능 부호
...
그것의 오퍼랜드 인 경우를 제외하고 3sizeof
운영자 또는 단항&
연산자, 또는 어레이를 초기화하는 데 이용되는 문자열의 문자 입력 '의 배열을 갖는 표현 유형을 ' 의 '포인터'유형의 표현으로 변환된다 " 형 배열 개체의 초기 요소를 가리키고는 좌변 아니라고 '. 배열 객체에 레지스터 스토리지 클래스가 있으면 동작이 정의되지 않습니다.
다음 코드가 주어집니다.
int main(void)
{
int arr[10];
foo(arr);
...
}
에 대한 호출 foo
에서 배열 표현식 arr
은 sizeof
또는 의 피연산자가 &
아니므로 해당 유형은 6.2.3.1/3에 따라 "10 요소 배열 int
"에서 "포인터"로 암시 적으로 변환됩니다 int
. 따라서 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에서 함수 매개 변수에 배열 표기법을 사용하면 자동으로 포인터 선언으로 변환됩니다.
아니요, 그들 사이에는 차이가 없습니다. 테스트를 위해 Dev C ++ (mingw) 컴파일러에서이 C 코드를 작성했습니다.
#include <stdio.h>
void function(int* array) {
int a =5;
}
void main() {
int array[]={2,4};
function(array);
getch();
}
IDA에서 이진 파일의 두 호출 버전의 .exe에서 주 함수를 분해하면 아래와 같이 정확히 동일한 어셈블리 코드를 얻습니다.
push ebp
mov ebp, esp
sub esp, 18h
and esp, 0FFFFFFF0h
mov eax, 0
add eax, 0Fh
add eax, 0Fh
shr eax, 4
shl eax, 4
mov [ebp+var_C], eax
mov eax, [ebp+var_C]
call sub_401730
call sub_4013D0
mov [ebp+var_8], 2
mov [ebp+var_4], 4
lea eax, [ebp+var_8]
mov [esp+18h+var_18], eax
call sub_401290
call _getch
leave
retn
따라서이 호출의 두 버전 사이에는 차이가 없습니다. 적어도 컴파일러는 이들을 동등하게 위협합니다.