c·c++/c 프로그래밍

c언어에서 인자의 전달에 관하여

바로이순간 2012. 7. 7. 22:03

네이버 답변 중에서 nodo2010님의 답변입니다.

=====================================================

오늘은 값의 전달과 참조 전달에 대해서 공부를했는데

이해를 한거같은데 뭔가 찝찝함이 남아서 여쭤볼려고합니다.


#include <stdio.h>

void swapbyval(int,int);

void swapbyref(int *,int *);

main()

{

 int a=2,b=7;

 printf("a=%d,b=%d\n",a,b);

 swapbyval(a,b);

 printf("a=%d,b=%d\n",a,b);

 swapbyref(&a,&b);

 printf("a=%d,b=%d\n",a,b);

}

void swapbyval(int x,int y)

{

 int temp;

 temp = x;

 x=y;

 y=temp;

}

void swapbyref(int *x,int *y)

{

 int temp;

 temp = *x;

 *x=*y;

 *y=temp;

}

 

-----------------------------------------------------

읽어 보시고, 질문에 스스로 답을 해 보세요.

 

C언어에는 참조에 의한 정보 전달은 없습니다. 이 부분은 반드시 바로 잡아야 하는 내용입니다. 

값에 의한 정보 전달만이 있습니다. 


기억장소에 저장된 값을 복사하는 값에 의한 정보 전달 방법과 

기억장소를 식별할 때 사용되는 값인 주소를 복사하는 값에 의한 정보 전달 방법이 있습니다. 


그래서 swapbyval 함수는 기억장소에 저장된 값을 복사하는 정보 전달 방법이고 

swapbyref 함수는 주소를 복사하는 값에 의한 정보 전달입니다.


그러면 질문자가 작성한 코드가 어떻게 작동하는지를 설명하도록 하겠습니다. 

참고해 보세요. 


함수가 호출되어 실행되면 함수에서 필요한 데이터들, 

즉 다시 말해서 자동변수를 할당할 기억장소를 운영체제로부터 할당받게 되는 데 

이를 스택 세그먼트라고 합니다. 


스택 세그먼트가 할당되면, 자동변수(들)에 대해 기억장소가 할당됩니다. 

이렇게 할당된 변수에 값을 쓰고 읽어 함수에 기술된 명령(들)이 처리되는 것입니다. 

그리고 함수가 끝나면 스택 세그먼트가 할당 해제됩니다. 


그러면 시작해 봅시다. 

코드를 컴파일, 링크 그리고 적재하면 운영체제에 의해서 main 함수가 호출됩니다. 


main 함수 스택 세그먼트가 할당되고, a와 b 자동변수들에 대해 기억장소가 할당되고, 

초기화되어 있기 때문에 a와 b에 2와 7이 저장됩니다.


 

그리고 printf 함수가 호출되어 화면에 출력하는데 결과는 위에 있는 그림을 참고하면 다음과 같습니다.

a=2,b=7


다음은 swapbyval 함수가 호출됩니다. 

호출문장을 보면, 실인수로 a와 b가 적혀 있습니다. 


따라서 a와 b에 저장된 값을 복사하는 값에 의한 정보 전달을 하는 것입니다. 

swapbyval 함수가 호출되면, swapbyval 함수에서 필요한 데이터들, x,y 

그리고 temp를 할당하기 위해 스택 세그먼트가 할당되고, 변수들에 대해 기억장소가 할당됩니다. 


그리고 main에서 복사되어진 값들, 2와 7이 매개변수인 x와 y에 저장됩니다. 

그리고 temp는 쓰레기가 저장됩니다. 


main 함수 스택 세그먼트 아래에 swapbyval 스택 세그먼트가 할당됩니다. 

아래 그림과 같이 작도되어야 합니다.


 


이 상태에서 swapbyval이 실행되면 x와 y의 값들이 교환됩니다. 

따라서 다음과 같이 작도됩니다.


 


그리고 swapbyval의 함수 블록의 끝을 나타내는 중괄호를 만나면 함수가 끝나게 되고, 

함수 스택 세그먼트가 할당 해제됩니다. 


따라서 main 함수 스택 세그먼트 아래에 그려졌던 함수 스택 세그먼트가 없어지게 됩니다. 

따라서 다음과 같이 그려집니다.



이 상태에서 printf 함수가 호출되어 출력하면 다음과 같이 출력됩니다.

a=2,b=7


다음은 swapbyref 함수를 호출합니다.

 

swapbyref가 호출되어 실행되면 main 함수 스택 세그먼트 아래에 스택 세그먼트가 할당되고, 

x, y 그리고 temp에 대해 기억장소들이 할당됩니다. 


그리고 main 함수에서 함수 호출식에서 사용된 &a와 &b로 

main 함수에 할당된 기억장소 a와 b의 주소를 구해서  복사하는 값에 의한 정보 전달을 하여 


x에 main 함수에 할당된 변수 a의 주소, y에 main 함수에 할당된 변수 b의 주소를 저장하게 됩니다. 

이렇게 주소를 구해서 값으로 복사하기 때문에 값에 의한 정보 전달입니다. 


swapbyref 함수가 호출된 직후 메모리 맵은 같습니다.


 


이러한 메모리 상태에서 swapbyref 함수가 실행되면 main 함수에 할당된 a와 b에 저장된 값이 교환됩니다. 


왜냐하면 *x는 x에 저장된 값인 주소를 갖는 기억장소인 main 함수에 할당된 a에 저장된 값을 의미합니다. 

따라서 swapbyref 함수가 끝나기 전 메모리 맵은 다음과 같습니다.



그리고 swapbyref 함수의 끝을 나타내는 닫는 중괄호를 만나면 

swapbyref 함수 스택 세그먼트가 할당 해제됩니다. 


main 함수 스택 세그먼트가 할당 해제됩니다. 

이 때 메모리 맵은 다음과 같습니다.


   


이 상태에서 printf 함수로 화면에 출력하면 다음과 같이 출력되어야 합니다.

a=7,b=2

 

이렇게 포인터와 함수를 배울 때는 메모리 맵을 이용하면 쉽게 배울 수 있습니다.

C언어에서 정보 전달은 따라서 값에 의한 정보 전달만이 존재하는 것입니다.


메모리 맵을 이용한 포인터와 함수를 배우고자 하시면 다음 책을 참고해 보세요.

책은 "C를 배우면 함수를 잘 만들어야 한다"입니다.