길벗 코딩 자율학습단 13기
https://cafe.naver.com/gilbutitbook/12930
C언어 입문 p.235 ~ 249
포인터로 배열에 접근하기
#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]);
}
int* ptr = arr;
for (int i = 0; i < 3; i++) {
printf("포인터 변수 ptr[%d]의 값 : %d\n", i, ptr[i]);
}
return 0;
}
//배열 arr[0]의 값 : 5
//배열 arr[1]의 값 : 10
//배열 arr[2]의 값 : 15
//포인터 변수 ptr[0]의 값 : 5
//포인터 변수 ptr[1]의 값 : 10
//포인터 변수 ptr[2]의 값 : 15
포인터 변수에 배열을 값으로 넣으면 포인터 변수는 배열의 첫 번째 요소의 주소, 즉 배열의 시작 주소를 가리키게 된다. 그러면 포인터 변수는 시작 주소로 배열에 접근해 요소의 값을 하나씩 가져올 수 있다.
#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]);
}
int* ptr = arr;
for (int i = 0; i < 3; i++) {
printf("포인터 변수 ptr[%d]의 값 : %d\n", i, ptr[i]);
}
//포인터 변수에서 값 바꾸기
ptr[0] = 100;
printf("배열 arr[0]의 값 : %d\n", arr[0]);
printf("포인터 변수 ptr[0]의 값 : %d\n", ptr[0]);
//printf("포인터 변수 ptr[0]의 값 : %d\n", *(ptr + 0));
return 0;
}
//배열 arr[0]의 값 : 5
//배열 arr[1]의 값 : 10
//배열 arr[2]의 값 : 15
//포인터 변수 ptr[0]의 값 : 5
//포인터 변수 ptr[1]의 값 : 10
//포인터 변수 ptr[2]의 값 : 15
//배열 arr[0]의 값 : 100
//포인터 변수 ptr[0]의 값 : 100
포인터 변수에 값을 직접 넣어서 바꾼 후에 출력해보면 포인터 변수의 값도 바뀌고 배열의 값도 바뀐다. 즉 포인터 변수가 직접 배열의 요소에 접근해서 값을 바꿀 수 있으며, arr배열과 ptr이 같은 역할을 한다고 볼수 있다. 단 ptr은 필요하다면 arr과 같은 배열을 값으로 넣을 수 있지만 반대로는 불가능하다.
주석처리된 코드를 보면 배열의 요소를 가리키는 것을 ptr[0]과 같이 표현하지 않고 *(ptr + 0)로 표현하였다. ptr은 배열이 시작되는 주소, 즉 첫 번째 요소의 주소를 가지고 있다. ptr [i]는 배열 첫 번째 요소의 주소로부터 i번째에 해당하는 요소의 값을 가져온다는 의미이기에 *(ptr + i) 과 문법적으로 같은 문장이다.
실습 - 포인터로 두 변수의 값 교환하기
#include <stdio.h>
void swap(int a, int 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의 주소 : 0000009D84AFF864
//b의 주소 : 0000009D84AFF884
//swap() 함수 호출 전 = > a : 10, b : 20
//swap() 함수 안에서 a의 주소 : 0000009D84AFF840
//swap() 함수 안에서 b의 주소 : 0000009D84AFF848
//swap() 함수 안 = > a : 20, b = 10
//swap() 함수 호출 후 = > a : 10, b : 20
swap 함수를 호출하기 전과 후의 a, b의 값이 바뀌지 않고 같지만, swap 함수 안에서만 바뀌었다. 이는 변수의 주소를 보면 알 수 있는데, a의 주소와 swap() 함수 안의 a의 주소가 다르다. 이는 두 a가 서로 다른 변수라는 뜻으로, swap() 함수 안에서 다른 공간에 변수 a가 새로 만들어진 것이다. 이처럼 함수를 호출하면서 전달값으로 변수를 넘기면 호출한 함수 안에서는 변수 자체가 아닌 전달받은 변수의 값만 복사해서 사용한다. 이를 값에 의한 호출(call by value) 라고 한다.
#include <stdio.h>
void swap_addr(int* a, int* b);
int main(void) {
int a = 10;
int b = 20;
printf("a의 주소 :%p\n", &a);
printf("b의 주소 :%p\n", &b);
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);
}
//a의 주소 : 0000005CE42FFA84
//b의 주소 : 0000005CE42FFAA4
//swap_addr() 함수 호출 전 = > a : 10, b : 20
//swap_addr() 함수 안 = > a : 20, b : 10
//swap_addr() 함수 호출 후 = > a : 20, b : 10
함수 안에 변수의 주소 자체를 넘기면 주소에 저장된 값을 바꾼다. 이처럼 함수를 호출하면서 전달값으로 변수의 주소를 넘기면 호출한 함수 안에서 변수의 주소를 참조해 값을 사용하거나 수정할 수 있다. 이를 참조에 의한 호출 (call by reference)라고 한다.
정확히 얘기하면 C언어에는 값에 의한 호출 개념만 있으며 참조에 의한 호출은 없다. 다만 포인터를 이용해 함수 안에서 주소값을 참조해 값을 변경할 수 있어서 참조에 의한 호출을 흉내내는 것 뿐이다.
실습 - 포인터로 배열의 값 바꾸기
#include <stdio.h>
void changeArray(int* ptr);
int main(void) {
int arr[3] = { 10, 20, 30 };
changeArray(arr);
for (int i = 0; i < 3; i++) {
printf("%d\n", arr[i]);
}
return 0;
}
void changeArray(int* ptr) {
ptr[2] = 50;
}
//10
//20
//50
포인터 변수에 배열을 저장하면 포인터로 값을 바꿀 때 원래 배열의 주소로 접근하여 값을 변경한다. 배열의 시작 주소인 첫 번째 요소의 주소를 전달하기에 시작 주소를 기준으로 지정한 요소의 위치를 찾아 값을 바꿀 수 있다.
알게된 것 / 궁금한 것
1) 포인터 변수에 배열을 넣으면 배열의 첫 번째 주소를 가지는 것
2) 값에 의한 호출과 참조에 의한 호출
후기 (。˃ ᵕ ˂ )b
어렵다!!!!! 헷갈린다. 원래 이번 장 프로젝트까지 끝내고 싶었는데 뇌가 과부하 온것 같다. 포인터,,, 어렵다,,,
'Programming > TIL' 카테고리의 다른 글
[TIL] C언어 입문 12일차 (다차원 배열) (0) | 2025.03.06 |
---|---|
[TIL] C언어 입문 11일차 (프로젝트 - 물고기 키우기) (0) | 2025.03.05 |
[TIL] C언어 입문 9일차 (포인터로 변수 다루기) (0) | 2025.03.02 |
[TIL] C언어 입문 8일차 (배열에 문자열 저장하기) (0) | 2025.02.26 |
[TIL] C언어 입문 7일차 (배열 선언, 배열 초기화) (0) | 2025.02.25 |