본문 바로가기
C언어

야메 C언어 강좌: 11. 포인터(1)

by 케찹이 2022. 1. 14.

이전 강좌를 작성하고 굉장히 오랜 시간이 지나서야 해당 강좌를 작성하기 때문에 이전 강좌와 연결되지 않는 부분이 있더라도 양해부탁드리고 봐주시길 바라겠습니다.

 

사실 야메 강좌이기 때문에 포인터에 대해서 어떻게 설명을 해야 할지 굉장히 고민이 되었습니다. 저는 포인터를 처음 배우고 이전까지 배운 내용에 대한 회의감과 C언어와 멀어지는 느낌을 받기까지 하였습니다. 하지만 개인마다 포인터를 배우고 더욱 흥미를 느끼는 사람도 있기 때문에 최대한 간단하게 포인터에 대해 얘기하겠지만 그래도 최소한의 요점정도는 적어두도록 하겠습니다. (더욱 자세한 내용을 원하시는 분들은 다른 블로그를 찾으시길 바라겠습니다)

 

 

 

포인터에 대해서 알기 전에 주소라는 개념을 알고 계셔야 합니다.

"엥 주소????? 갑자기????" 라고 생각이 들겁니다. 그렇습니다 여러분이 생각하는 그 개념의 주소와 같은 역활을 합니다. 다만 형태가 다를 뿐이지요. 우리가 실생활에서 자주 사용하는 주소는 "서울 용산구 XX아파트 10X동 10XX호" 와 같은 형식입니다. 실생황에서 여러분의 집이 주소가 있듯이. 컴퓨터세상에서도 각 데이터는 주소가 존재합니다. 그리고 그들의 주소는 16진수로 되어있으며 0x12345678와 같은 형식으로 되어있습니다.

글만으로 이해하기 힘든 분들을 위해 이상한 그림으로 예시를 가지고 왔습니다. 위는 용산아파트 101동의 구조입니다. 아마 긴 복도형 아파트인것 같습니다. 그리고 아주 상식적으로 1층부터 101호, 102호, 103호....순서대로 호수가 존재하죠.  

복도형 아파트는 이렇게 생겼습니다

위와 똑같은 예시의 그림에서 글자 몇개만 바꾸게 되면 컴퓨터세상에서의 주소 개념을 알 수 있습니다. 

컴퓨터에서 우리가 만들은 int, char, float등등의 변수는 메모리라는 공간에 저장이 되어있습니다. 위 사진에서 하나의 박스가 아파트의 한 집이며 그안에는 데이터가 살고 있습니다. 그리고 그집의 주소가 0x어쩌구저쩌구하는 숫자들입니다. 이 주소는 16진수로 표시가 되어있기 때문에 9다음 크기로는 A, B, C, D, E순서입니다. (실제로 변수가 어떤식으로 저장되거나 메모리의 구조가 알고 싶으신 분들은 제가 나중에 다루는 구체적인 강의를 봐주시거나 다른분의 블로그를 참조해주시기 바랍니다.)

**주의** 실제로 하나의 변수가 하나의 박스안에 저장되는 것이 아니니 유의해주시길 바라겠습니다!!! 

 

위 그림의 설명이 어려우셨다면 이거 하나만 기억해주시길 바라겠습니다. "컴퓨터세상에서 변수들도 자신의 집주소가 있다!" 자 그럼 포인터는 무엇이냐면 포인터는 주소를 저장하는 변수입니다. 마치 int, char, float와 같이 새로운 변수입니다. 다시, 포인터는 주소를 저장하는 변수입니다. 

 

"포인터가 변수의 일종이면 변수 설명할때 해주지 왜 지금하냐????"

 

왜 그랬냐면 사용법과 개념이 조금 복잡했기 때문입니다. 포인터의 사용법은 다른 변수와 다르게 영어 알파벳이 아니고 특수문자 *로 표시합니다. 

 

int* pointer;
char* pointer;
float* pointer;

위와 같은 형식처럼 포인터를 사용하게 됩니다. 처음 보시는 분들은 벌써 멘붕에 빠져버리실 수도 있습니다. 하지만 조금만 생각해보면 나름 쉬운 개념이 차근차근히 살펴보도록 하겠습니다. 

int*는 int형식의 데이터의 주소를 저장합니다. 

(벌써 어려우신가요? 괜찮습니다 참고로 포인터는 C언어에서 제일 어려운 문법이기 때문에 다시 한번 천천히 읽어주시기 바라겠습니다.) 

그럼 pointer에는 어떤식으로 값이 저장되는지도 한번 봅시다. 

 

int data = 400;
int* pointer = &data;

data라는 변수를 처음 생성하고 pointer변수에 &data값을 저장하고 있는 코드입니다. 

&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

이 &는 어떤 의미일까요? &를 변수이름 앞에 적게 되면 해당 변수의 주소값을 의미하게 됩니다. 그럼으로 &data의 값은 pointer값이 되는 것입니다. 그래서 만약 &data값과 pointer값을 출력하게 되면 같은 값을 출력하게 될것입니다. 

 

마지막으로 다시 한번 *에 대해 얘기하고 이번 글은 여기서 마무리하겠습니다.

"  *얘기했잖어 포인터변수들 선언할때 앞에 찍는거라며??????? "

아 이번에는 생긴건 같은데 다른 의미를 가지고 있습니다. 헷갈리시나요? 바로 밑 코드를 살펴보겠습니다.

#include<stdio.h>

int main(){
	int data = 400;
	int* pointer = &data;
	printf("%d\n", data);
	printf("%d\n", *pointer);
	
	*pointer = 500;
	printf("%d\n", data);
	printf("%d\n", *pointer);
}

위 코드의 결과를 보시면 아래와 같습니다.

400
400
500
500

처음 선언할때에 사용하던 *는 해당 변수가 포인터변수임을 분별하게 해주는 *이었습니다. 하지만 그 이후로 사용된 *은 해당 주소의 값을 표현합니다. 이걸 "포인터로 가리킨다"라고 말하기도 합니다. 이렇게 사용함으로써 포인터변수가 가리키는 변수의 값을 직접 변경할 수 있게 된것입니다. 

 

이전 코드에 대한 상황을 그림으로 표현해보았습니다. 위 그림은 일단 변수들만을 선언해놓은 상태입니다. data값은 400이고 data의 주소는 0x12345678이죠. 그리고 pointer의 값은 data의 주소인 0x12345678입니다.

 

이때 pointer가 data를 가리킬 때 즉 data의 값을 직접 변경하려 할때 (이전 코드에서 *pointer = 500을 말하는 것입니다.) 아래와 같이 보여지게 됩니다.

 

여기까지 포인터에 대한 아주 기초적인 설명이었습니다. 사실 "야메"치고는 꽤나 어려웠던 설명인것 같았습니다. 포인터, 많이 어렵습니다. 여러분이 지금 당장 이해하지 못하는게 정상입니다. 지금 머리가 복잡하면 머리를 비우고 잠시 쉬다가 다시 한번 읽는 것을 권장해드리겠습니다. 혹시 저의 설명이 너무 모호하거나 상징적이어서 이해가 되지 않는다면 댓글로 알려주시기 바라겠습니다. 포인터를 배우면 포인터를 활용할 수 있는 방안들이 많기 때문에 그러한 활용 방법들을 다음 글에서 설명해보도록 하겠습니다. 

 

한번 직접 코드를 써보시고 이런식 저런식으로 값들을 출력해보시며 익숙해지고 실험해보시기 바라겠습니다. 아 그리고 이쯤되면 예전에 scanf가 다시 생각나지 않으신가요? 네, 이 글을 왠만큼 이해하셨다면 scanf의 &은 주소를 뜻하는 것이 맞습니다. 

댓글