programing

C의 기능에 전달되는 어레이와 어레이 포인터의 차이

goodsources 2022. 7. 30. 19:16
반응형

C의 기능에 전달되는 어레이와 어레이 포인터의 차이

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

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

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

상당히 긴 어레이에서 함수를 호출하면 이 두 함수는 다르게 동작하며 스택에서 더 많은 공간을 차지합니까?

먼저 몇 가지 표준어가 있습니다.

6.7.5.3 기능 선언기(시제품 포함)
...
7 ''배열''로서의 파라미터 선언형식'은 "유자격 포인터"로 조정해야 한다.type'', 여기서 유형 수식자(있는 경우)는 다음 중 지정된 수식자입니다. [그리고. ]배열 유형 파생 모델입니다.키워드가 static에도 표시됩니다. [그리고. ]배열 유형 도출의 경우, 함수에 대한 각 호출에 대해 대응하는 실제 인수 값은 크기 식에 의해 지정된 수 이상의 요소를 가진 배열의 첫 번째 요소에 대한 접근을 제공해야 한다.

즉, 다음과 같이 선언된 함수 파라미터는T a[]또는T a[N]선언된 것처럼 취급됩니다.T *a.

그러면 어레이 파라미터가 포인터로 선언된 것처럼 취급되는 이유는 무엇일까요?이유는 다음과 같습니다.

6.3.2.1 Lvalue, 배열 및 기능 지정자
...
3 피연산자의 피연산자일 경우 제외한다. sizeof연산자 또는 단항자 &operator 또는 배열 초기화에 사용되는 문자열 리터럴로, 배열의 유형 "array"를 가진 식입니다.type'은 type이 "type"인 식에 변환됩니다.type'은 배열 객체의 초기 요소를 가리키며 l값이 아닙니다.어레이 개체에 레지스터 스토리지 클래스가 있으면 동작이 정의되지 않습니다.

다음 코드가 지정됩니다.

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

문의처foo, 어레이 표현식arr피연산자도 아닙니다.sizeof또는&따라서 그 유형은 암묵적으로 "10-소문자 배열"에서 변환됩니다.int"에 "접속int6.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])
{
  ...
}

대응하는 실제 파라미터a10개 이상의 요소를 포함하는 배열이어야 합니다.

차이는 순전히 구문론적이다.C에서는 함수 파라미터에 배열표기를 사용하면 자동으로 포인터 선언으로 변환된다.

아니요, 그 둘 사이에는 차이가 없어요.이 C코드를 Dev C++(mingw) 컴파일러로 작성했습니다.

#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

따라서 이 콜의 두 버전 사이에는 차이가 없습니다.적어도 컴파일러는 이들을 동등하게 위협하고 있습니다.

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

반응형