포인터는 값을 직접 담는 변수가 아니라, 다른 값이 놓인 위치를 저장하는 변수입니다. 이 카드에서는 포인터 기본 문법과 원본 수정 패턴을 같이 봅니다.
int *ptr,&value,*ptr를 한 번에 다시 보고 싶다- 왜 값을 복사할 때와 주소를 넘길 때 결과가 달라지는지 정리하고 싶다
NULL과 잘못된 포인터가 왜 위험한지 확인하고 싶다
숏컷 코드
값을 복사하면 원본은 그대로 남고, 주소를 넘기면 원본을 읽고 수정할 수 있습니다.
int value = 10;
int *ptr = &value;
printf("%d\n", *ptr);
*ptr = 20;
printf("%d\n", value);문법
포인터 기본 문법은 보통 아래 네 가지를 같이 봐야 합니다.
T *p: 포인터 선언&x: 변수의 주소 얻기*p: 그 주소의 값을 읽거나 쓰기NULL: 아직 유효한 대상을 가리키지 않는 상태
int value = 10;
int *ptr = &value;
printf("%d\n", value);
printf("%d\n", *ptr);포인터가 필요한 가장 흔한 이유는 원본 공유와 원본 수정입니다.
void double_in_place(int *p) {
*p *= 2;
}
int score = 95;
double_in_place(&score);
printf("%d\n", score);값 복사로 넘기면 함수 안 변경은 밖으로 안 나가지만, 주소를 넘기면 같은 원본을 같이 보게 됩니다.
void change_value(int n) {
n = 0;
}
int count = 7;
change_value(count);
printf("%d\n", count); /* 7 */이 예시는 "값 복사"라서 호출자 원본이 안 바뀝니다. 포인터를 넘길 때와 가장 크게 갈리는 지점입니다.
기본 개념
포인터는 문법보다 역참조 시점의 유효성이 더 중요합니다.
int *ptr = NULL;
if (ptr != NULL) {
*ptr = 42;
}NULL은 "빈 포인터"에 가깝고, 아직 유효한 대상을 가리키지 않는 상태를 뜻합니다. C 포인터 버그의 대부분은 유효하지 않은 주소를 믿고 역참조하는 습관에서 시작합니다.
void reset_value(int *p) {
if (p != NULL) {
*p = 0;
}
}
int count = 7;
reset_value(&count);체크포인트
T *p는 포인터 선언입니다.&x는 주소를 얻고,*p는 그 주소의 값을 읽거나 씁니다.- 값을 복사해도 되면 일반 인자를 쓰고, 호출자 원본을 바꿔야 하면 포인터를 넘깁니다.
- 아직 대상을 못 정한 포인터는
NULL로 시작하는 편이 안전합니다. - 포인터는 선언보다 역참조 시점의 유효성이 더 중요합니다.
주의할 점
초기화하지 않은 포인터나 이미 사라진 대상을 가리키는 포인터를 역참조하면, 크래시보다 먼저 데이터 손상이 일어날 수 있습니다.
int *p;
*p = 42;
int *dangerous(void) {
int local = 10;
return &local;
}- 초기화하지 않은 포인터는 쓰면 안 됩니다.
- 지역 변수 주소를 반환하면 함수가 끝난 뒤 무효한 주소를 넘기게 됩니다.
- 유효한 대상 주소 또는
NULL만 포인터에 넣는 습관이 중요합니다.
참고 링크
1 sources