■ Call by value
오늘은 제목부터 영어 쓰네요~ㅋ
콜 바이 벨류? 이게 뭔 말일까요?
value 는 값이란건 알겠는디.
값을 부른다? 호출한다?
다음 예제 한 마리를 봅시다.
오늘 설명할 것에 대한 예제는 전형적이라서
다른 강의나 책을 본다해도 이거하고 비슷한 예제가.
훗~!
#include
void swap(int x,int y);
int main(void)
{
int X,Y;
X=3;
Y=6;
printf("함수 호출전:X=%d , Y=%d\n",X,Y);
swap(X,Y);
printf("\n!함수 호출후:X=%d , Y=%d\n",X,Y);
return 0;
}
void swap(int x,int y)
{
int temp; //임시
temp=x;
x=y;
y=temp;
printf("함수 내: X=%d , Y=%d\n",x,y);
}
함수 호출전:X=3, Y=6
함수 내: X=6, Y=3
!함수 호출후:X=3, Y=6
이라고 나오죠?
아마 이걸 짠 프로그래머는
///////////////////////////
함수 호출전:X=3, Y=6
함수 내: X=6, Y=3
!함수 호출후:X=6, Y=3
///////////////////////////
이렇게 결과과 나오길 즉 두 값을 교환하려고 함수를 작성한거 같은데
그 놈의 함수가 자기 내에서는 값을 바꾸더니 함수 호출이 끝나니깐 그대로네요.
당연한 예기죠?
(참~ 함수내에 temp는 두 값을 교환하기위해 임시로 설정한겁니당..꺄둑)
혹시 왜 값이 안바껴?!? 라고 질문 하시는 철없는 분들.
함수 강의 할때 변수의 지역성에 대해 공부했죠?
기억 안나시면 7강 다시 보셈~ㅋ
좀 추가적으로 설명하여 어려운 부분으로 들어가면 일단 메인에서
X,Y가 함수인자로 통해 swap에 넘어 옵니다
그래서 swap이란 함수 자체내에서 급히 임시로
void swap(int x,int y)
넘겨온 인자에 int x, int y라 되있으니깐 int형인 x,y를 만들고 각각 X,Y를 들어가게 합니다.
그리고 swap함수는 x,y를 가지고 놀고
문장을 수행하고 함수가 끝나게 되면 자동적으로 x,y는 없어지지요,(당연한거죠?)
쉽게 말해 x,y는 X,Y의 복사본이죠~!
X,Y의 값이 넘어 왔으니깐 swap함수는 단지 그 값을 복사해다 쓴셈이 되지요
x,y를 가지고 놀아봤자 원본인 X,Y엔 아무런 변화가 없는 겁니다.
근데 주소가 넘어오면 이야기가 달라집니다.
암튼 다시 쉽게 넘어와서
이렇게 값을 전달하면 그 함수 내에서만 놀다가 지내끼리 다 해먹고 정작 메인에서는
원하는 결과를 얻을수 없죠.
그러탐 함수를 호출해서 두 값을 교환하는 프로그램은 어떻게 짤까요?
■ Call by adress, reference
콜 바이 어드레스(주소) 주소를 넘기면 됩니다.
주소개념은 저번엔 포인터 강의때 알아봤져?
아직도 잘 모르시겠으면 질문 주세요.
콜 바이 어드레스는 어떻게 쓸까요?
역시 다음 예제 한 마리를 살펴봅시당.
#include
void swap(int *x,int *y);
int main(void)
{
int X,Y;
X=3;
Y=6;
printf("함수 호출전:X=%d , Y=%d\n",X,Y);
swap(&X,&Y);
printf("\n!함수 호출후:X=%d , Y=%d\n",X,Y);
return 0;
}
void swap(int *x,int *y)
{
int temp; //임시루 쓰기 위해~!
temp=*x;
*x=*y;
*y=temp;
printf("함수 내: X=%d , Y=%d\n",*x,*y);
}
그럼 결과는
함수 호출전:X=3, Y=6
함수 내: X=6, Y=3
!함수 호출후:X=6, Y=3
와우 원하는 결과가 나왔군요..
이번 예제는 먼저번 예제와 틀린점이 있군요.
void swap(int *x,int *y);
함수 선언부를 보니깐 포인터가 보이네요~!
내려가서 함수 호출부분을 볼까요?
swap(&X,&Y);
&X라면 X의 주소라는거 전에 설명 했죠? 인자를 포인터를 사용한다고 선언 했으니깐
우리가 주소를 인자로 넘기는건 인지상정.....
이겠죠..ㅋㅋ
함수 부분을 잘 봅시다.
먼저번 예제와 다른 부분이있죠.
자~!
일단 함수에 주소가 넘겨져 왔으므로
우리는 메인에 있는 직접 X와 Y를 다루는 셈이 됨니다.!!
Wow~! 원츄죠?
일단 교환부분을 봅시다.
temp=*x;
*x=*y;
*y=temp;
아까와는 다르게 *x,*y라고 쓰고 있지요.
우리가 불러온건 메인에 있는 X,Y에 있는 주소이지요?
우리가 바꾸고자 하는건 그것의 값이니깐
*x,*y를 사용하는거지요 그냥 x,y라고 쓰면 주소를 교환하는 셈이 되어 에러가 나죠
*x,*y가 값을 나타낸다는거 저번 포인터 강의때 배웠죠?..헤헤.
출력부분도
printf("함수 내: X=%d , Y=%d\n",*x,*y);
이렇게 바꿨지요..
암튼 이렇게 하니깐 원하는 걸 얻었네요 ^^/
다시 설명하면
call by value 예제는 값을 불러왔으므로 메인에 있는 X,Y가 아니라
그 함수에 임시로 생긴 x,y에 X,Y를 넣고 다룬다음
함수가 끝나서 임시로 생긴 x,y도 끝나니깐.
메인에 있는 X,Y의 값의 변화가 없었던 겁니당.
근데 이렇게 주소를 넘기면 메인에 있는 X,Y를
함수에서도 직접 다룰 수가 있죠~!
즉 복사본이 아닌 원본 자체로써 말입니다.
다시 아까처럼 어렵게 들어 갈까요?
이번엔 &X,&Y가 넘어 오는데 주소네요
void swap(int *x,int *y)
이처럼 주소가 온다구 인자에 포인터가 붙었죠?
그럼 아까 call by value에서 x, y를 만들어 X, Y를 들어가게한 것 처럼
마찬가지로 이번에두 임시로 *x,*y를 만들어 &X, &Y를 들어가게 합니다
이렇게 x=&X 가 y=&Y가 들어가게 하여
x,y가 X,Y를 가르키게 되는 포인터가 되는거죠!
자 그럼 swap에서 생긴 포인터 x,y를 제어하면
x,y가 가르키고 있는 메인에 있는 X,Y도 따라서 제어가 되겠지요?
이제 swap함수는 복사본이 아닌 원본을 직접 제어 한 것이 되는거죠~!
이해 가나요?
흠 어려워졌나?
이거와 비슷한 다음 약간 C++개념이 들어간
call by reference 개념의 예제 한마리를 볼까요?
그 예제 보기 전에 이 예제 함 보아요
#include
int main(void)
{
int a=3;
int &b=a;
printf("%d %d\n",a, b);
return 0;
}
실행하면 어때요? a랑 b랑 같죠?
int &b=a 이건 a에다 일종의 별명 b를 붙여준 것이라고 생각하면 되요.
a라는 보자기가 있는데 그것의 이름은 b라고도 불려진다,
바로 이거죠!!
이제 다음 예제를 BoA요~!
#include
void swap(int &x,int &y);
int main(void)
{
int X,Y;
X=3;
Y=6;
printf("함수 호출전:X=%d , Y=%d\n",X,Y);
swap(X,Y);
printf("\n!함수 호출후:X=%d , Y=%d\n",X,Y);
return 0;
}
void swap(int &x,int &y)
{
int temp; //임시
temp=x;
x=y;
y=temp;
printf("함수 내: X=%d , Y=%d\n",x,y);
}
실행시키면
함수 호출전:X=3, Y=6
함수 내: X=6, Y=3
!함수 호출후:X=6, Y=3
같은 결과가 나오죠?
일단 메인에서 swap함수 인자로 X,Y 값이 넘어 옵니다.
void swap(int &x,int &y)
근데 여기 인자를 보니 int &x, int &y라고 선언되어 있네요!
&x는 X의 별명이 되겠고 &y는 Y의 별명이 되겠네요?
즉 &x나 X는 같다는 얘기 즉
swap는 따로 복사본을 만드는게 아니라
원본 그 자체를 가지고 제어한다는 얘기
그래서 이런 결과가 나온 거랍니다
!! 참고로 이 예제에 쓰인 &를 주소라고 생각하지 마셈! 다른 개념이랍니당. !!
http://cafe.naver.com/sjs25.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=11863
여기가 출처입니다.
■ 어드레스와 레퍼렌스의 차이
주소공간에 메모리를 할당하냐 안하냐의 차이는 크다고 봅니다.
콜바이 어드레스는 메모리공간을 무조건 4바이트만큼 할당하고 콜바이 레퍼런스는
가인수 로서 메모리공간을 할당하지않고 이미 있는 메모리에 참조로서 전달되는것이니 메모리로서 보면 좀 다르다고 볼수 있겠네요
■ 어드레스?
Call By Address 기법으로 실인수의 주소값을 전달하면 실인수를 간접적으로 참조살 수 있으므로 사용자 정의 함수에 실인수 값을 변경할 수 있습니다. 물론 Call By Address도 기억공간이 옮겨가는 것이 아닙니다. 변수의 주소가 전달됨으로서 단지 값만 전달되었을 때와는 다른 결과를 기대할수 있습니다.
Call By Referance 함수에 레퍼런스 변수를 가인수로 지정하는 기법입니다.
'프로그래밍 > 참고' 카테고리의 다른 글
#include , <stdio.h>, main (0) | 2013.02.27 |
---|---|
문자열 관리 함수들 총집합! (0) | 2013.02.24 |
함수 기초 (0) | 2013.02.04 |
함수 (0) | 2013.02.03 |
지역 변수 / 전역 변수 (0) | 2013.01.31 |