c언어 포인터의 기본 개념 이해하기 1

앞으로 "C언어의 꽃" 포인터에 대해서 공부해보는 시간을 가져보겠습니다. 포인터에 대해서는 조금씩 조금씩 쪼개서 살펴보도록 하겠습니다. 

 

포인터(Pointer)란?

C언어에서의 포인터는 메모리의 주소를 가지는 변수입니다.!! 자료형에 대해서 공부할때 각각의 자료형마다 할당되어지는 메모리가 있다고 공부했었습니다. 예를 들어서 int형 변수를 선언하게 될때는 4byte의 메모리를 할당한다고 공부했습니다. int형의 a변수를 선언하게 되면 a변수 이름을 가진 주소를 할당받게 됩니다. 포인터 변수는 이러한 주소를 저장할 수 있는 변수입니다! 

 

예를 들어서 땅을 사서 건물을 짓는다고 생각해봅시다. 

어떤 건물을 지을건가 건물의 형태를 먼저 알아야 합니다.
학교, 영화관, 주택, 아파트, 체육관 등등 

다음은 건물을 지을 땅을 알아봐야 겠죠?
서울, 대전, 대구, 부산

건물의 이름을 정합니다. 
홍지대학교, 홍지아파트, 홍지주택, 홍지체육관 등등 

저는 서울에 땅을사고 대학교를 만들어 "홍지대학교"를 만들었습니다!! 

지금까지 공부했던 것과 똑같습니다. 학교라는 타입의 홍지대학교를 선언했을 뿐이죠? 하지만 지금까지는 이게 어느 땅에 저장되어있는지를 모르고 그냥 사용했던 것 뿐입니다. "홍지대학교"가 만들어지면서 땅을 선택했습니다. int a를 선언할때에도 a를 저장할 땅 즉 메모리 공간을 할당 받았습니다. 지금까지는 어디에 만들어졌는지 관심이 없었을 뿐입니다. 

 

위에 "홍지대학교"를 만들면서 할당받는 땅에는 주소가 있습니다 "서울시 00구 00동 324-1번지"의 주소가 있습니다. 이와 같이 int a를 선언하면서 만들어지는 a의 땅(메모리)에도 주소(0x100)가 있습니다.  

 

그래서 포인터 변수는 어떤 녀석이냐!! 바로 네비게이션인 티맵카카오네비를 생각해보시면 됩니다. 

 

우리는 티맵에서 "서울대학교"를 검색하면 "서울 관악구 관악로1"이라는 주소를 알 수 있습니다. C언어에서의 포인터는 말 그대로 포인터 변수를 활용해 a를 검색하면 a값으 주소인 "0x100"이라는 주소를 알 수 있게 됩니다. 

 

포인터(Pointer)의 선언

 

#include <stdio.h>

int main(void) {

	int a;
	int *ptr = &a;

	printf("a변수의 주소값은 %u입니다 \n", &a);
	printf("a값의 주소는 %d 입니다 \n", ptr);
	printf("포인터 ptr의 주소 %u 입니다", &ptr);
}

위에 소스를 보면 int *ptr = &a; 의 선언을 보실 수 있습니다 이는 ptr 포인터변수에 변수 a의 주소를 대입해라 라는 의미를 가지게 됩니다. 

1. 포인터 변수의 선언은 변수명 앞에 *를 추가하여 선언할 수 있다. 
2. 주소 연산자(&)를 사용하면 해당 변수의 시작 주소를 구해줍니다. 

위에 소스를 실행시키면 결과 값은 어떻게 나올까? 

 

첫번째 실행했을때의 a의 주소는 5241444 였고 두번째 a의 주소는 1702660 입니다. 위에서 설명했던 학교는 매번 같은자리에 있지만 컴퓨터에서는 변수를 선언할때 임의의 메모리(땅)를 할당받기 때문에 매번 변수의 주소가 달라질 수 있습니다

 

위에 결과값에서 알수 있는건 포인터 변수인 ptr 또한 변수이기 때문에 주소값을 갖는다는 것입니다. 첫번째 결과값을 보면 int형의 a변수의 주소값은 5241444 ~ 5241447 까지 4byte의 공간을 할당받고 있고 다시 int형인 ptr의 주소는 5241432 ~ 5241435까지의 공간을 할당받게 되는 것입니다. 

 

 

int *ptr = &a;

 

 위에서는 한줄에 포인터 선언과 초기화까지하는 방법으로 알아봤는데 꼭 초기화를 할 필요는 없습니다. 

 

	int a;
	int* ptr;
	ptr = &a;

이처럼 int * ptr;로 선언한 포인터 변수를 선언하고 난 뒤에도 ptr 변수에  a의 주소값을 대입할 수 도 있습니다. 

 

포인터 변수 ptr을 선언하고 주소 연산자(&)를 사용해서 &a값을 ptr에 넣는다면 이건 단순히 포인터 변수인 ptr이 a를 가리키고 있는 것이지만 다르게 생각하면 해당 주소의 값을 변경할 수 있다는 의미이기도 합니다. 

 

예를 들어 "홍지대학교"에 택배를 보낸다고 가정해봅시다! 

"홍지대학교"에 택배를 보냄!    ==       홍지대학교 = 택배;
"홍지대학교"주소에 택배를 보냄!  ==  &홍지대학교 = 택배; 

홍지대학교에 택배를 보내나 홍지대학교가 있는 주소에 택배를 보내나 어쨌든 홍지대학교라는 공간에 택배가 도착하게 될것입니다. 

 

이처럼 c언어에서는 포인터가 참조하고 있는 주소값에 데이터를 사용할때에는 특별한 연산자를 사용하게 되는데 이때 사용되는 연산자를 간접 참조 연산자(*)라고 합니다.

 

#include <stdio.h>

int main(void) {

	int a;
	int* ptr = &a;

	*ptr = 10;

	printf("a값은 %d 입니다", a);
}

포인터 변수 ptr에 변수 a의 주소값을 저장하고 간접 참조 연산자(*) 를 통해서 ptr에 10을 대입하게 되면 ptr이 가리키고 있는 a변수의 주소에 10을 대입하게 되는 것입니다. 즉 a값에 10을 대입하나 a값의 주소에 10을 대입하나 결과적으로 할당받은 공간에 10이 저장되게 되는 것 입니다. 

 

 

포인터를 사용하여 변수의 주소값을 확인하는 프로그램과 포인터의 간접 참조 연산자를 활용한 데이터 입력하기등의 예제를 직접 생각나는데로 만들어 보시면서 포인터의 사용법에 대해서 확인해보시기 바랍니다.

 

오늘은 포인터가 뭔지 포인터의 사용법에 대해서 공부했습니다. 다음에는 자료형에 따른 포인터의 크기와 포인터의 주소값에 대해서 공부해보는 시간을 가져보겠습니다. 

댓글

Designed by JB FACTORY