← 목록으로

🎯 3단계: 포인터 변수

주소를 저장하는 변수 = 포인터

일반 변수는 “값”을 저장하고, 포인터 변수는 “다른 변수의 주소”를 저장해요. 그래서 “그쪽을 가리킨다”고 해서 포인터(pointer)라고 부르죠.

*는 선언할 때는 “포인터예요”라고 알려 주고, 사용할 때는 “가리키는 곳의 값”을 가져올 때 써요.

그림으로 보기

int a = 10; int *p = &a; 라고 하면 (a는 변수 이름, p는 포인터 변수 이름):

변수 a (이름이 a인 정수 변수): [ 주소 0x1000 ] → 값: 10
↑ 가리킴
포인터 변수 p: [ 주소 0x2000 ] → 값: 0x1000 (변수 a의 주소)

그래서 *p는 “p가 가리키는 곳(변수 a가 있는 0x1000 번지)에 가서 뭐가 있어? → 10”이에요.

코드로 확인하기

아래 코드를 [실행]으로 바로 실행해 보세요.

a와 *p가 둘 다 10으로 나오고, &a와 p가 같은 주소로 나오면 정확히 이해한 거예요!

✅ 3단계 정리

📋 실습 과제

과제 1 int a = 10, b = 20;과 포인터 p를 선언한 뒤, 먼저 p = &a;로 *p를 출력하고, 그다음 p = &b;로 바꾼 뒤 다시 *p를 출력하세요. (10, 20이 순서대로 나와야 합니다.)

✏️ 여기서 직접 실습해 보세요

모바일에서도 이 창에서 수정·포맷·실행·복사할 수 있어요. [실행]으로 바로 결과를 볼 수 있습니다.

참고 정답 코드 (클릭하여 펼치기)
#include <stdio.h>

int main() {
    int a = 10, b = 20;
    int *p = &a;
    printf("p가 a를 가리킬 때 *p: %d\n", *p);
    p = &b;
    printf("p가 b를 가리킬 때 *p: %d\n", *p);
    return 0;
}
과제 2 포인터 p는 a를, 포인터 q는 b를 가리키게 한 뒤, *p, *q, p, q를 각각 출력해 보세요.

여기서 직접 작성·실행해 보세요. [실행]으로 결과를 확인할 수 있어요.

과제 2 참고 정답 코드 (클릭하여 펼치기)
#include <stdio.h>

int main() {
    int a = 10, b = 20;
    int *p = &a, *q = &b;
    printf("*p = %d, *q = %d\n", *p, *q);
    printf("p = %p, q = %p\n", (void*)p, (void*)q);
    return 0;
}

🔬 심화 학습

NULL 포인터

아직 “아무것도 가리키지 않는” 상태를 나타낼 때 NULL을 넣어요. *p를 쓰기 전에 반드시 p가 유효한 주소를 가리키는지 확인하는 습관이 중요해요.

심화 참고 코드 (클릭하여 펼치기)
#include <stdio.h>

int main() {
    int *p = NULL;   /* 아무것도 가리키지 않음 */
    if (p == NULL)
        printf("p는 아직 아무 주소도 가리키지 않습니다.\n");
    /* *p를 여기서 쓰면 안 됨! */
    return 0;
}

void* 란?

void*는 “어떤 타입의 주소든 담을 수 있는” 포인터예요. 주소만 옮기고, 실제로 값을 쓸 때는 다시 올바른 타입으로 바꿔 써요.