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, 배열 및 기능 부호
...
그것의 오퍼랜드 인 경우를 제외하고 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 개 이상인 배열이어야합니다 .
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.
'programing' 카테고리의 다른 글
View의 Hibernate Open Session이 나쁜 습관으로 간주되는 이유는 무엇입니까? (0) | 2020.08.15 |
---|---|
풀에서 JDBC 연결 닫기 (0) | 2020.08.15 |
UnicodeDecodeError : 'ascii'코덱이 위치 1의 바이트 0xef를 디코딩 할 수 없습니다. (0) | 2020.08.15 |
Angular Material 2 구성 요소의 'cdk'는 무엇입니까? (0) | 2020.08.15 |
Linux에서 모든 직렬 장치 (ttyS, ttyUSB, ..)를 열지 않고 찾는 방법은 무엇입니까? (0) | 2020.08.15 |