Programming/C, C++

코딩 자율 학습단 12일차 - 포인터로 배열 다루기

주눅 2024. 7. 14. 13:28

드디어 7장...

7장의 주제는 포인터다 ㅠ.ㅠ;;

못하는 건 아닌데... 처음 배울 때 엄청 헤맸어서 좋은 생각은 안 든다 ㄱㅡ

 

 

딴소리지만

교수님이 강의시간에 이 짤 보여주셨던거 생각난다

ㅋㅋ

 

시작


#include <stdio.h>

int main(void) {
	int 철수 = 1;
	int 영희 = 2;
	int 민수 = 3;

	printf("철수네 주소: %p, 암호: %d\n", &철수, 철수);

	return 0;
}

실행 결과

 

위의 예제와 같이 변수를 선언하면 메모리에 변수의 이름을 가진 공간이 생긴다.

그리고, 그 변수 공간의 위치를 나타내는 주소를 갖게 된다.

 

변수의 이름 앞에 &를 붙여 출력하면 변수의 주소를 알 수 있다.

이때 서식지정자로는 포인터를 의미하는 %p를 사용한다.

(예제의 000000731C6FF5C4가 출력된 '철수'의 주소다)

 

즉, 철수라는 이름으로 변수를 선언하고 초기화했더니

메모리에서 000000731C6FF5C4라는 위치에 '철수' 공간을 할당하고,

그 안에 값 '1'을 넣어 저장한 것이다.

 

 

같은 방법으로 함께 선언한 나머지 두 변수의 주소도 알아낼 수 있다.

실행 결과

실행 결과 값의 끝자리가 04, 24, 44로

주소 간에 일정한 간격을 두고 있는 것을 알 수 있는데,

 

이건 변수들이 스택 메모리에 할당되기 때문이라고 한다.

스택 메모리란 일반적으로 함수 호출 시 지역 변수를 저장하는 메모리 영역이다.

 

(잘 모르겠어서 자세히 읽진 않음) 우리는 정수형 변수 int를 사용했는데,

int는 일반적으로 4바이트를 사용하므로 변수들의 주소 값이 4의 배수만큼 차이 나는 것이라고 한다

+ㅅ+ 신기...


 

자료형 * 변수명;

 

변수를 선언할 때 앞에 *을 붙여 선언한 변수를 포인터 변수, 또는 포인터라고 하는데,

포인터를 사용하면 다른 변수의 주소와 값을 알아낼 수 있다.

포인터 변수는 메모리의 주소값을 저장하는 변수다.

 

#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", 미션맨, *미션맨);

	return 0;
}

실행 결과

 

포인터 변수명 앞에 *를 붙이면 포인터 변수가 가리키는 주소의 값을 알 수 있다.

 

#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;
}

실행 결과

 

이처럼 포인터 변수를 사용하면 다른 변수의 주소와, 그 안에 담긴 값을 알아낼 수 있다.

 


 

또, 포인터를 사용하면 다른 변수의 값을 쉽게 변경할 수 있다.

#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;
}

실행 결과

 

실행 결과, 미션맨이 *미션맨의 값에 *미션맨 x 3을 저장해

철수네 집의 주소를 1에서 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", 미션맨, *미션맨);

	미션맨 = &영희;
	*미션맨 = *미션맨 * 3;
	printf("미션맨이 암호를 바꾼 곳의 주소: %p, 암호: %d\n", 미션맨, *미션맨);

	미션맨 = &민수;
	*미션맨 = *미션맨 * 3;
	printf("미션맨이 암호를 바꾼 곳의 주소: %p, 암호: %d\n", 미션맨, *미션맨);

	return 0;
}

실행 결과

 

나머지 집의 주소도 같은 방법으로 모두 변경했다.

 

예제를 통해 포인터 변수는 다른 변수의 주소를 알아낼 수 있고,

알아낸 변수의 값을 직접 변경할 수 있다는 것을 알아보았다.


 

#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("\n미션맨이 방문한 곳의 주소: %p, 암호: %d\n", 미션맨, *미션맨);

	미션맨 = &철수;
	*미션맨 = *미션맨 * 3;
	printf("미션맨이 암호를 바꾼 곳의 주소: %p, 암호: %d\n", 미션맨, *미션맨);

	/*포인터 변수를 추가해 값 바구기*/
	printf("\n >>스파이가 미션을 수행하는 중 <<\n");

	int* 스파이 = 미션맨;
	*스파이 = *스파이 - 1; // 철수 = 철수 - 1; 
	printf("스파이가 방문한 곳의 주소: %p, 암호: %d\n", 스파이, *스파이);


	미션맨 = &영희;
	printf("\n미션맨이 방문한 곳의 주소: %p, 암호: %d\n", 미션맨, *미션맨);

	미션맨 = &영희;
	*미션맨 = *미션맨 * 3;
	printf("미션맨이 암호를 바꾼 곳의 주소: %p, 암호: %d\n", 미션맨, *미션맨);

	/*포인터 변수를 추가해 값 바구기*/
	printf("\n >>스파이가 미션을 수행하는 중 <<\n");
	스파이 = 미션맨; 
	*스파이 = *스파이 - 1; // 영희 = 영희 - 1;
	printf("스파이가 방문한 곳의 주소: %p, 암호: %d\n", 스파이, *스파이);


	미션맨 = &민수;
	printf("\n미션맨이 방문한 곳의 주소: %p, 암호: %d\n", 미션맨, *미션맨);

	미션맨 = &민수;
	*미션맨 = *미션맨 * 3;
	printf("미션맨이 암호를 바꾼 곳의 주소: %p, 암호: %d\n", 미션맨, *미션맨);

	/*포인터 변수를 추가해 값 바구기*/
	printf("\n >>스파이가 미션을 수행하는 중 <<\n");
	스파이 = 미션맨;
	*스파이 = *스파이 - 1; // 민수 = 민수 - 1;
	printf("스파이가 방문한 곳의 주소: %p, 암호: %d\n", 스파이, *스파이);

	printf("\n >> 철수, 영희, 민수가 집에 와서 바뀐 암호를 보고 놀람 <<\n");
	printf("철수네 주소: %p, 암호: %d\n", &철수, 철수);
	printf("영희네 주소: %p, 암호: %d\n", &영희, 영희);
	printf("민수네 주소: %p, 암호: %d\n", &민수, 민수);

	return 0;
}

실행 결과

실행 결과, 변수의 값이 실제로 바뀌었음을 확인할 수 있다.

 

다음과 같이 포인터 변수는 주소를 이용해

주소에 해당하는 변수의 값을 읽거나 직접 바꿀 수 있으며,

포인터 여러 개가 같은 주소, 하나의 메모리 공간을 가리킬 수도 있다.