먼저 C에서 포인터를 도대체 왜 쓰는 것일까? 다른 언어에서는 포인터가 없는데, 유독 C언의 포인터가 C언어를 처음 배우는 사람에게 진입장벽이 되는 것 같다.(사실 다른언어에는 포인터가 없을 뿐이지, 그와 같은 역할을 하는 다른 요소들이 있다.)
아래 예시를 한번 봐보자.
void local(int);
int main(void)
{
int var = 10;
printf("변수 var의 초깃값은 %d입니다.\n", var);
local(var);
//loca에서 매개변수로 받는 var은 지역변수로서, main의 var과 메모리상에 같은곳을 바라보는 변수가 아니다.
printf("local() 함수 호출 후 변수 var의 값은 %d입니다.\n", var);
return 0;
}
void local(int var)
{
var += 10;
}
C를 배워보신 분들은, 정확한 이유는 모르더라도, 직관적으로 main에서 var값을 printf 해보면 그 결과 값은 20이 아니라 10으로 변함이 없음을 알수가 있다.
그 이유는 local에서 매개변수로 받는 int var이 main에 있는 int var과 같은 값이 아니기 때문이다.
같은 이름으로 되어 있는데, 같은 값이 아니라니?
C언어에서는 함수의 재사용성을 높히고, 프로그램에 혼선을 주지 않게 하기 위해서, 함수에서 선언된 변수는 지역변수라 하여 해당 함수내에서만 영향을 끼치고, 해당 함수의 호출이 끝나면 메모리에서 지워버리는 휘발성 변수로 관리를 한다.
그렇기에, 같은 이름의 var이라고 할지라도, 함수간에 호출할 시에 같은 변수로 생각되지 않는다.
메모리 주소를 각기 다르게 갖고 있는 이름만 같은 별개의 변수가 된다.
같은 이름의 변수를 서로 주고 받아도, 해당 변수는 같은 메모리주소에 있는 같은 값이 아닌, 그저 값만(Value)주고 받는 것이다. 그래서 이러한 변수 전달행위를 call by value 라고 한다. 값에 의한 전달. 즉 값만 전달한다는 것이다.
그렇다면 포인터는 어떨때 쓰이는가? 함수간에 특정 변수의 메모리 주소를 정확히 지정하여 주고받기 위함이다. 변수 값만을 전달하여 휘발되어 버리고 마는 것이 아니라, 주소값을 정확히 전달하여 함수간에 목적하는 값의 주소를 정확히 전달하여 그 값의 수정도 가능하도록 하기 위함이다.
예시를 다시 고쳐서 봐보자.
void local(int*);
int main(void)
{
int var = 10;
printf("변수 var의 초깃값은 %d입니다.\n", var);
local(&var);
//loca에서 매개변수로 받는 var은 지역변수로서, main의 var과 메모리상에 같은곳을 바라보는 변수가 아니다.
printf("local() 함수 호출 후 변수 var의 값은 %d입니다.\n", var);
return 0;
}
void local(int* var)
{
*var += 10;
}
위 소스의 printf 값은 10에 10이 더해진 20이 된다.
위 소스에서는 포인터를 사용하여 주소값을 정확히 local함수에 전달하였고, local함수도 그 변수가 그 변수라는 것을 메모리 주소를 통해 정확히 인식하고, 해당 메모리 주소의 값에 +10을 함으로서 값이 변경이 된다. 이를 call by reference라고 부른다. 참조에 의한 전달.
그렇다면, 다른 언어에는 왜 포인터가 없는 것일까?
언어가 고도화 되면서 개발자의 메모리 컨트롤 재량을 최소화 시켜 프로그램의 혼선을 막기 위함으로 보인다.
그러나, 자바와 파이썬에도 call by reference 할수 있는 방법이 있다. 변수값만을 전달하는 것이 아닌, 클래스를 통해 만들어진 인스턴스 객체 자체를 전달을 하면, 특정 메모리 주소를 전달하는 포인터와 같은 효과를 누릴수가 있다.
인스턴스는 스택에 저장되어 사라지는 휘발성 지역변수가 아니라 heap메모리에 저장되는 비휘발성 객체로서, 인스턴스를 매개변수로 전달하게 되면, 전달받은 함수 입장에서는 해당 변수의 메모리상의 위치를 정확히 알 수 있게 된다. 그래서 C언어의 포인터로 주소를 전달한것과 같은 효과를 주어 call by reference가 가능하게 되는 것이다.
'프로그래밍 > 기타' 카테고리의 다른 글
docker mysql DB와 django 연동 (0) | 2022.06.26 |
---|---|
파이썬의 함수, 클래스, 인스턴스 (0) | 2022.01.22 |