Programming/TIL

[TIL] C언어 입문 9일차 (포인터로 변수 다루기)

catPaw 2025. 3. 2. 00:49

 

길벗 코딩 자율학습단 13기

https://cafe.naver.com/gilbutitbook/12930
C언어 입문 p.217 ~ 234


변수와 메모리의 관계

변수를 선언하면 메모리에 해당 변수의 이름을 가진 공간이 생긴다. 이 공간의 위치를 나타내는 주소는 변수명 앞에 &를 붙여 출력하면 알수 있다. 서식지정자는 %p를 사용하며, 메모리 주소를 16진수 형태로 출력한다. 

#include <stdio.h>

int main(void) {
	int 철수 = 1;
	int 영희 = 2;
	int 민수 = 3;
	//변수의 주소 출력
	printf("철수네 주소 : %p, 암호 : %d\n", &철수, 철수);
	printf("영희네 주소 : %p, 암호 : %d\n", &영희, 영희);
	printf("민수네 주소 : %p, 암호 : %d\n", &민수, 민수);
	return 0;
}

//철수네 주소 : 000000316C0FF8D4, 암호 : 1
//영희네 주소 : 000000316C0FF8F4, 암호 : 2
//민수네 주소 : 000000316C0FF914, 암호 : 3

주소는 변수 철수가 메모리의 어느 위치에 있는지 나타내며, 암호는 변수의 값이 나온다. 


포인터로 다른 변수의 주소와 값 알아내기

변수를 선언할 때 앞에 *를 넣어 선언한 변수를 포인터 변수 또는 포인터라고 한다. 포인터 변수는 메모리의 주소값을 저장하는 변수이다.

#include <stdio.h>

int main(void) {
	int 철수 = 1;
	int 영희 = 2;
	int 민수 = 3;
	//변수의 주소 출력
	printf("철수네 주소 : %p, 암호 : %d\n", &철수, 철수);
	printf("영희네 주소 : %p, 암호 : %d\n", &영희, 영희);
	printf("민수네 주소 : %p, 암호 : %d\n", &민수, 민수);
	//포인터 변수 선언과 값 출력
	int* 미션맨;
	미션맨 = &철수;
	printf("미션맨이 방문한 곳의 주소 : %p, 암호 : %d\n", 미션맨, *미션맨);
	미션맨 = &영희;
	printf("미션맨이 방문한 곳의 주소 : %p, 암호 : %d\n", 미션맨, *미션맨);
	미션맨 = &민수;
	printf("미션맨이 방문한 곳의 주소 : %p, 암호 : %d\n", 미션맨, *미션맨);
	return 0;
}

//철수네 주소 : 000000316C0FF8D4, 암호 : 1
//영희네 주소 : 000000316C0FF8F4, 암호 : 2
//민수네 주소 : 000000316C0FF914, 암호 : 3
//미션맨이 방문한 곳의 주소 : 000000316C0FF8D4, 암호 : 1
//미션맨이 방문한 곳의 주소 : 000000316C0FF8F4, 암호 : 2
//미션맨이 방문한 곳의 주소 : 000000316C0FF914, 암호 : 3

포인터 변수에는 철수라는 변수의 주소가 들어있으므로 이 값을 그대로 출력하면 철수네 주소를 알 수 있다. 변수의 값은 포인터 변수명 앞에 *를 붙이면 알수 있다. 해당 주소로 가서 값을 가져오는 것이다.


포인터로 다른 변수의 값 바꾸기

포인터 변수를 이용하여 변수의 값을 불러오고(*사용) 그 값을 변경할 수 있다. 이때 주소는 그대로이나 값만 변한다.

#include <stdio.h>

int main(void) {
	int 철수 = 1;
	int 영희 = 2;
	int 민수 = 3;
	//변수의 주소 출력
	printf("철수네 주소 : %p, 암호 : %d\n", &철수, 철수);
	printf("영희네 주소 : %p, 암호 : %d\n", &영희, 영희);
	printf("민수네 주소 : %p, 암호 : %d\n", &민수, 민수);
	//포인터 변수 선언과 값 출력
	int* 미션맨;
	미션맨 = &철수;
	printf("미션맨이 방문한 곳의 주소 : %p, 암호 : %d\n", 미션맨, *미션맨);
	미션맨 = &영희;
	printf("미션맨이 방문한 곳의 주소 : %p, 암호 : %d\n", 미션맨, *미션맨);
	미션맨 = &민수;
	printf("미션맨이 방문한 곳의 주소 : %p, 암호 : %d\n", 미션맨, *미션맨);
	//포인터 변수로 바꾼 값 출력
	미션맨 = &철수;
	*미션맨 *= 3;
	printf("미션맨이 암호를 바꾼 곳의 주소 : %p, 암호 : %d\n", 미션맨, *미션맨);
	return 0;
}

//철수네 주소 : 000000316C0FF8D4, 암호 : 1
//영희네 주소 : 000000316C0FF8F4, 암호 : 2
//민수네 주소 : 000000316C0FF914, 암호 : 3
//미션맨이 방문한 곳의 주소 : 000000316C0FF8D4, 암호 : 1
//미션맨이 방문한 곳의 주소 : 000000316C0FF8F4, 암호 : 2
//미션맨이 방문한 곳의 주소 : 000000316C0FF914, 암호 : 3
//미션맨이 암호를 바꾼 곳의 주소 : 000000316C0FF8D4, 암호 : 3

포인터 추가하기

다른 포인터를 추가하여 값으로 기존의 포인터를 넣는다면 기존 포인터가 알아낸 주소를 똑같이 알 수 있다. 즉 포인터 변수 2개는 하나의 메모리 공간을 가리킬 수 있다. 

#include <stdio.h>

int main(void) {
	int 철수 = 1;
	int 영희 = 2;
	int 민수 = 3;
	//변수의 주소 출력
	printf("철수네 주소 : %p, 암호 : %d\n", &철수, 철수);
	printf("영희네 주소 : %p, 암호 : %d\n", &영희, 영희);
	printf("민수네 주소 : %p, 암호 : %d\n", &민수, 민수);
	//포인터 변수 선언과 값 출력
	int* 미션맨;
	미션맨 = &철수;
	printf("미션맨이 방문한 곳의 주소 : %p, 암호 : %d\n", 미션맨, *미션맨);
	미션맨 = &영희;
	printf("미션맨이 방문한 곳의 주소 : %p, 암호 : %d\n", 미션맨, *미션맨);
	미션맨 = &민수;
	printf("미션맨이 방문한 곳의 주소 : %p, 암호 : %d\n", 미션맨, *미션맨);
	//포인터 변수로 바꾼 값 출력
	미션맨 = &철수;
	*미션맨 *= 3;
	printf("미션맨이 암호를 바꾼 곳의 주소 : %p, 암호 : %d\n", 미션맨, *미션맨);
	//포인터 변수 추가하여 값 바꾸기
	int* 스파이 = 미션맨;
	*스파이 -= 1;
	printf("스파이가 방문한 곳의 주소 : %p, 암호 : %d\n", 스파이, *스파이);
	return 0;
}

//철수네 주소 : 000000316C0FF8D4, 암호 : 1
//영희네 주소 : 000000316C0FF8F4, 암호 : 2
//민수네 주소 : 000000316C0FF914, 암호 : 3
//미션맨이 방문한 곳의 주소 : 000000316C0FF8D4, 암호 : 1
//미션맨이 방문한 곳의 주소 : 000000316C0FF8F4, 암호 : 2
//미션맨이 방문한 곳의 주소 : 000000316C0FF914, 암호 : 3
//미션맨이 암호를 바꾼 곳의 주소 : 000000316C0FF8D4, 암호 : 3
//스파이가 방문한 곳의 주소 : 000000316C0FF8D4, 암호 : 2

주소는 같지만 값은 바뀌었다. 이렇게 포인터 변수로 값을 바꾸면 원래 변수의 값을 확인했을 때도 바뀌어 있는 것을 확인할 수 있다. 포인터 변수도 다른 변수와 마찬가지로 주소가 있으며, &포인터변수명 으로 확인 가능하다.


알게된 것 / 궁금한 것

1) 포인터 변수


후기 (。˃ ᵕ ˂ )b

이틀이나 쉬고 공부하니 머리가 굳었는지 글이 잘 안읽혔다. 포인터로 주소를 확인하는 부분까지는 생각보다 어렵지 않았다. 이제 배열로 들어가면 어려울것 같아서 걱정이다.