📌 변수와 메모리
#include <stdio.h>
int main(void) {
int 철수 = 1;
int 영희 = 2;
int 민수 = 3;
printf("철수네 주소: %p, 암호 : %d\\n", &철수, 철수);
//철수네 주소: 0000003D3211F8E4, 암호 : 1 << 출력
//영희네 주소 : 00000011B72FF564, 암호 : 2
//민수네 주소 : 00000011B72FF584, 암호 : 3
return 0;
}
- 101호 사는 철수를 우리는 101호라고 읽지만, 실제 메모리에서는 어떤 값인지 모름.
- 이 값을 알아내려면? 변수명 앞에 **&**를 붙여 출력, 서식지정자는 포인터를 의미하는 %p
- 철수의 주소 위치에 철수라는 이름으로 공간을 할당하고 그 안에 1이라는 값을 넣음.
📌 포인터로 다른 변수의 주소와 값 알아내기
#include <stdio.h>
int main(void) {
int 철수 = 1;
int 영희 = 2;
int 민수 = 3;
printf("철수네 주소: %p, 암호 : %d\\n", &철수, 철수);
printf("영희네 주소: %p, 암호 : %d\\n", &영희, 영희);
printf("민수네 주소: %p, 암호 : %d\\n", &민수, 민수);
/*
철수네 주소 : 000000C2FD70F714, 암호 : 1
영희네 주소 : 000000C2FD70F734, 암호 : 2
민수네 주소 : 000000C2FD70F754, 암호 : 3
*/
//포인터 변수 선언과 값 출력
int* 미션맨;
미션맨 = &철수;
printf("미션맨이 방문한 곳의 주소: %p, 암호: %d\\n", 미션맨, *미션맨);
//미션맨이 방문한 곳의 주소: 000000C2FD70F714, 암호 : 1
return 0;
}
- 포인터 변수는 메모리의 주소값을 저장하는 변수, 앞에 *가 있음.
- 변수 미션맨에는 철수의 주소가 할당되어 있어서 이대로 출력하면 철수의 주소를 알 수 있음.
- 암호는 철수의 주소에 들어있는 값이어서 포인터 변수명 앞에 *을 붙이면 됨.
📌 포인터로 다른 변수의 값 바꾸기
각 집의 암호에 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", &민수, 민수);
/*
철수네 주소 : 000000C2FD70F714, 암호 : 1
영희네 주소 : 000000C2FD70F734, 암호 : 2
민수네 주소 : 000000C2FD70F754, 암호 : 3
*/
//포인터 변수 선언과 값 출력
int* 미션맨;
미션맨 = &철수;
printf("미션맨이 방문한 곳의 주소: %p, 암호: %d\\n", 미션맨, *미션맨);
//미션맨이 방문한 곳의 주소: 000000C2FD70F714, 암호 : 1
*미션맨 = *미션맨 * 3;
printf("미션맨이 암호를 바꾼 곳의 주소: %p, 암호: %d\\n", 미션맨, *미션맨);
//미션맨이 암호를 바꾼 곳의 주소: 000000C2FD70F714, 암호 : 3
return 0;
}
- *미션맨 포인터 변수의 값을 곱하기 3으로 선언함.
📌 포인터 추가하기
미션맨들의 장소에 도둑이 등장이라니..
도둑이 등장해서 암호 -1씩 훔쳐감.
#include <stdio.h>
int main(void) {
int 철수 = 1;
int 영희 = 2;
int 민수 = 3;
printf("철수네 주소: %p, 암호 : %d\\n", &철수, 철수);
printf("영희네 주소: %p, 암호 : %d\\n", &영희, 영희);
printf("민수네 주소: %p, 암호 : %d\\n", &민수, 민수);
/*
철수네 주소 : 000000C2FD70F714, 암호 : 1
영희네 주소 : 000000C2FD70F734, 암호 : 2
민수네 주소 : 000000C2FD70F754, 암호 : 3
*/
//포인터 변수 선언과 값 출력
int* 미션맨;
미션맨 = &철수;
printf("미션맨이 방문한 곳의 주소: %p, 암호: %d\\n", 미션맨, *미션맨);
//미션맨이 방문한 곳의 주소: 000000C2FD70F714, 암호 : 1
*미션맨 = *미션맨 * 3;
printf("미션맨이 암호를 바꾼 곳의 주소: %p, 암호: %d\\n", 미션맨, *미션맨);
//미션맨이 암호를 바꾼 곳의 주소: 000000C2FD70F714, 암호 : 3
printf("\\n=== 도둑 등장 === \\n");
int* 도둑 = 미션맨;
*도둑 = *도둑 - 1;
printf("도둑이 방문한 곳의 주소: %p, 암호: %d\\n", 도둑, *도둑);
//도둑이 방문한 곳의 주소: 000000C2FD70F714, 암호 : 2
return 0;
}
- 철수네 암호는 1이었는데 미션맨이 3으로 바꾸고 도둑이 훔쳐서 2로 바뀜. 철수는 집 못들어가겠다.
📌 포인터로 배열 다루기
#include <stdio.h>
int main(void){
int arr[3] = {5,10,15};
for (int i = 0; i < 3; i++) {
printf("배열 arr[%d]값 : %d\\n", i, arr[i]);
//배열 arr[0]값 : 5
//배열 arr[1]값 : 10
//배열 arr[2]값 : 15
}
int* ptr = arr;
for (int i = 0; i < 3; i++) {
printf("포인터 변수 ptr[%d]의 값: %d\\n", i, ptr[i]);
//포인터 변수 ptr[0]의 값 : 5
//포인터 변수 ptr[1]의 값 : 10
//포인터 변수 ptr[2]의 값 : 15
}
ptr[0] = 100;
ptr[1] = 200;
ptr[2] = 300;
for (int i = 0; i < 3; i++) {
printf("배열 arr[%d]값 : %d\\n", i, arr[i]);
//배열 arr[0]값 : 100
//배열 arr[1]값 : 200
//배열 arr[2]값 : 300
}
for (int i = 0; i < 3; i++) {
printf("포인터 변수 ptr[%d]의 값: %d\\n", i, ptr[i]);
//포인터 변수 ptr[0]의 값 : 100
//포인터 변수 ptr[1]의 값 : 200
//포인터 변수 ptr[2]의 값 : 300
}
return 0;
}
- 포인터 변수의 값을 바꾸기 전에는 배열의 초깃값 그대로 5, 10, 15가 출력이 됨.
- 값을 새로 넣으면 포인터 변수가 직접 배열의 각 요소에 접근해서 값을 바꿈.
📌 포인터로 값 교환하기
#include <stdio.h>
void swap(int a, int b);
int main(void) {
int a = 10;
int b = 20;
printf("swap() 함수 호출 전 => a: %d, b : %d\\n", a, b);
swap(a, b);
printf("swap() 함수 호출 후 => a: %d, b : %d\\n", a, b);
return 0;
}
void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
printf("swap() 함수 안 => a: %d, b: %d\\n", a, b);
}
- 이렇게 하면 a와 b의 값이 바뀌어서 나올 것 같지만 출력값은
swap() 함수 호출 전 => a: 10, b : 20
swap() 함수 안 => a: 20, b: 10
swap() 함수 호출 후 => a: 10, b : 20
- 함수에서는 a와 b가 값이 바꼈는데 호출 후의 값에는 그대로임. 왜 그럴까???
- 실제로는 두 변수 자체가 아닌 두 변수의 값만 전달해서 그럼. 무슨 소리냐면
int main(void) {
int a = 10;
int b = 20;
printf("a의 주소: %p\\n", &a);
printf("b의 주소: %p\\n", &b);
printf("swap() 함수 호출 전 => a: %d, b : %d\\n", a, b);
swap(a, b);
printf("swap() 함수 호출 후 => a: %d, b : %d\\n", a, b);
return 0;
}
void swap(int a, int b) {
printf("swap() 함수 안에서 a의 주소: %p\\n", &a);
printf("swap() 함수 안에서 b의 주소: %p\\n", &b);
int temp = a;
a = b;
b = temp;
printf("swap() 함수 안 => a: %d, b: %d\\n", a, b);
}
//a의 주소 : 0000000F1910F6C4
//b의 주소 : 0000000F1910F6E4
//swap() 함수 호출 전 = > a: 10, b : 20
//swap() 함수 안에서 a의 주소 : 0000000F1910F6A0
//swap() 함수 안에서 b의 주소 : 0000000F1910F6A8
//swap() 함수 안 = > a: 20, b : 10
//swap() 함수 호출 후 = > a: 10, b : 20
- 변수 a, b의 주소가 서로 다름. 이로서 main()함수에 a와 swqp()의 a는 다른 변수인 것을 알 수 있음.
- 전달값으로 변수를 넘기면 호출한 함수 안에서는 변수 자체가 아닌 전달받은 변수의 값만 복사해서 사용 >> 값에 의한 호출 이라고 부름.
#include <stdio.h>
void swap_addr(int * a, int * b);
int main(void) {
int a = 10;
int b = 20;
printf("swap_addr() 함수 호출 전 => a: %d, b : %d\\n", a, b);
swap_addr(&a, &b);
printf("swap_addr() 함수 호출 후 => a: %d, b : %d\\n", a, b);
return 0;
}
void swap_addr(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
printf("swap_addr() 함수 안 => a: %d, b: %d\\n", *a, *b);
}
//swap_addr() 함수 호출 전 => a: 10, b : 20
//swap_addr() 함수 안 => a: 20, b: 10
//swap_addr() 함수 호출 후 => a: 20, b : 10
- 함수를 호출하면서 전달값으로 변수의 주소를 넘기면 호출한 함수 안에서 변수의 주소를 참조해 값을 사용하거나 수정할 수 있음 >> 참조에 의한 호출이라고 부름.
'언어 > C' 카테고리의 다른 글
[코딩자율학습] 14일차 다차원 배열 (0) | 2024.03.21 |
---|---|
[코딩자율학습] 13일차 프로젝트 어항에 물주기 (0) | 2024.03.20 |
[코딩자율학습] 11일차 프로젝트: 자라나라 머리머리 (0) | 2024.03.18 |
[코딩자율학습] 10일차 배열과 문자열 (0) | 2024.03.15 |
[코딩자율학습] 9일차 프로젝트: 비밀번호 마스터 (0) | 2024.03.14 |