본문 바로가기

FALL in/G.MA' s C

[C프로그래밍] - 포인터


포인터 개념 / 선언과 초기화 

포인터(포인터 변수)는 변수의 주소값을 저장할수 있다. 

예를 들어, int a =10; 정수형 변수 a를 선언하고 10으로 초기화 했다.

변수a의 값은 메모리공간 어딘가에 저장되어진다. 

변수의 값은 모두 메모리공간 어딘가에 저장되어지는데 이 변수값에 접근하고 싶다면 이 변수가 어디 저장되어있는지 주소값을 알아야 한다. &a는 a의 값이 저장되어있는 메모리주소를 의미한다. 즉 &a는 a의 주소값이다. 그리고 변수의 주소값을 저장하는 변수를 포인터 변수라고 한다. &a(a의 주소값)을 저장하기위한 자료형은 포인터인 것이다. 

int* ptr = &a; 이와 같이 정수형 포인터 변수를 선언하고 초기화 해줄수있다. ptr이라는 변수에 a의 주소값을 넣었다. 여기서 int * 는 하나의 자료형이라고 생각하면 된다. 


포인터변수를 사용할때 주의할 점은 int* ptr = 10; 처럼 임의의 값을 넣으면 안된다. 메인 메모리안의 OS가 차지하는 영역을 건드릴수 있기 때문이다.

OS가 10번지를 사용중인데 사용자가 변수를 저장하기위해 그 영역을 빼앗은것이나 마찬가지가 된다.




포인터 구조와 연산 

int a=10, *ptr= &a; 를 선언했다면


위와 같은 메모리 영역에 a와 ptr변수의 값이 저장된다. (번지는 구조를 설명하기위해 임의로정한것이다.)

메모리 한칸당 1byte라고 생각하자.

정수인 a를 저장하기위해서는 4byte(4칸)이 필요하다. 

그리고 그 4칸에는 a변수의 값인 10이 저장된다.

ptr 변수의 영역(100번지~103번지)에는 a의 주소값인 20이 저장된다. 

포인터 변수에는 저장할 변수의 첫주소(시작주소)가 저장되므로 a의 첫주소인 20이 저장된것이다.

참고로 ptr은 4칸을 사용했는데 포인터 변수는 모두 4byte를 사용한다.(int *, char *, float*...모두 크기는 4byte)


a는? 10

&a 는? 20

ptr 는? 20

&ptr 는? 100 


*ptr 는? a  


*은 역참조 연산자 이다.

 ptr의 값(20)을 역으로 찾아가겠다는 것이다.

 20번지를 찾아가면 a의 값이 있으므로 *ptr은 a이다. (*ptr은 a의 별명이다.)


- 포인터의 연산

포인터연산은 자료형 크기만큼 더해지거나 빼진다.

예를 들어, ptr++; 이나 ptr = ptr+1; 을 실행하면 ptr은 21이 아니라 24가된다. ptr = ptr+2; 를 실행하면 ptr은 28이된다.

(*ptr)++; 을 실행하면  a의 값이 11로 바뀐다. *ptr은 a이기 때문이다. 즉 a++; 연산과 동일히다. 

a 는 *ptr과 동일하다고 생각하면 포인터를 다루는데 무리가 없을 것이다.


그러면 여기서 의문이 생길 수 있다. 

포인터 변수는 모두 4byte라면서, 왜 주소를 저장하는 변수의 자료형이 하나가 아니라 int*, char*, float*... 처럼 나누어져있을까.

그냥 단순히 pointer ptr = &a;처럼 pointer라는 하나의 자료형을 써도 될텐데 말이다.

이유는 이렇다. 


int a=10, *ptr= &a; 에서 

a의 주소값을 이용해 a에 접근하고 싶을때 

ptr의 역참조연산자를 쓸수있다. 

즉 *ptr = 14; 이렇게 a의 값을 14로 바꿀수있다. 

ptr에는 a의 시작주소값이 저장되어있기때문에 그 주소를 따라가 a값을 접근할수있다.

하지만 포인터 변수 ptr에는 a에 시작주소만 있고 얼마만큼 가져와야되는지 끝주소는 없다.

20번지에가서 4byte(a가 정수형 변수 이므로)만큼 읽어와서 14로 값을 바꿔야하는데 끝주소를 알려주지 않았다.

이 역할을 포인터의 자료형이 해준다. 즉 int *변수는 그 값을따라가서 4byte만큼 읽어오고, char*변수는 그 값을따라가서 2byte만큼 읽어올수있다. 

'FALL in > G.MA' s C' 카테고리의 다른 글

[C프로그래밍] - Call by Value vs. Call by Reference  (0) 2016.03.29
[C프로그래밍] - 메모리  (0) 2016.03.28
[C프로그래밍] - 재귀호출  (2) 2016.03.28
[C프로그래밍] - 구조체  (0) 2016.03.27
[C프로그래밍] - 배열  (0) 2016.03.27