programing

C에서 배열과 배열 포인터를 함수에 전달하는 것의 차이점

nasanasas 2020. 8. 15. 09:21
반응형

C에서 배열과 배열 포인터를 함수에 전달하는 것의 차이점


C에서 두 기능의 차이점은 무엇입니까?

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

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

실질적으로 긴 배열에서 함수를 호출하면이 두 함수가 다르게 동작할까요? 스택에서 더 많은 공간을 차지할까요?


첫째, 몇 가지 표준 :

(원형 포함) 6.7.5.3 함수 선언자
...
'배열'과 같은 파라미터도 7a 선언 유형 '' '으로 규정 포인터'로 조정된다 입력 타입 한정자 (있는 경우) 그 지정된 ', 내 []어레이 형의 유도. 키워드 static배열 유형 파생 [내부에도 표시되는 경우 ]함수에 대한 각 호출에 대해 해당 실제 인수의 값은 크기에 지정된만큼의 요소가있는 배열의 첫 번째 요소에 대한 액세스를 제공해야합니다. 표현.

그래서, 짧은에, 어떤 함수 매개 변수는 다음과 같이 선언 T a[]또는 T a[N]처리 것처럼 그것을 선언했다 T *a.

그렇다면 배열 매개 변수가 포인터로 선언 된 것처럼 처리되는 이유는 무엇입니까? 그 이유는 다음과 같습니다.

6.3.2.1 Lvalues, 배열 및 기능 부호
...
그것의 오퍼랜드 인 경우를 제외하고 3 sizeof운영자 또는 단항 &연산자, 또는 어레이를 초기화하는 데 이용되는 문자열의 문자 입력 '의 배열을 갖는 표현 유형을 ' 의 '포인터'유형의 표현으로 변환된다 " 배열 개체의 초기 요소를 가리키고는 좌변 아니라고 '. 배열 객체에 레지스터 스토리지 클래스가 있으면 동작이 정의되지 않습니다.

다음 코드가 주어집니다.

int main(void)
{
  int arr[10];
  foo(arr);
  ...
}

에 대한 호출 foo에서 배열 표현식 arrsizeof또는 의 피연산자가 &아니므로 해당 유형은 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 개 이상인 배열이어야합니다 .


The difference is purely syntaxic. In C, when the array notation is used for a function parameter, it is automatically transformed into a pointer declaration.


No, there is no difference between them. To test I wrote this C code in Dev C++(mingw) compiler:

#include <stdio.h>

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

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

When I disassemble main function in .exe of both calling versions of binary file in IDA I get exactly the same assembly code like below:

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

So there is no difference between the two versions of this call, at least the compiler threats them equally.

참고URL : https://stackoverflow.com/questions/5573310/difference-between-passing-array-and-array-pointer-into-function-in-c

반응형