topic난이도 · 약 35

포인터

변수의 주소를 저장하는 변수. `&`로 주소를 얻고 `*`로 역참조.

#C#포인터#실기핵심
왜 배우는가

C 실기의 50% 이상이 포인터와 얽혀 있다. 주소·값·역참조를 머리로 따라가는 훈련이 전부다.

포인터 변수는 다른 변수의 메모리 주소를 저장한다. `int *p = &a;`는 '변수 a의 주소를 p에 저장'이라는 뜻이며, `*p`로 그 주소에 있는 실제 값에 접근한다.

0 / 3
포인터 변수 p일반 변수 aint *p값 (주소)0x1000주소: 0x2A00int a10주소: 0x1000p가 a를 가리킴① 변수 선언int a = 10;포인터(주소 저장)일반 변수(값 저장)
① 변수 선언

변수 a를 선언하고 10을 저장. 메모리 어딘가의 주소(예: 0x1000)에 값 10이 놓인다.

① 변수 선언 → ② 포인터 연결 → ③ 역참조 대입 → ④ 값 변경. 단계를 탭해 메모리 모델을 따라가 보세요.
c
#include <stdio.h>
int main() {
    int a = 10;
    int *p = &a;      // p는 a의 주소를 가리킴
    printf("%d\n", *p);   // 10  (역참조로 a의 값)
    *p = 20;          // p가 가리키는 곳(=a)의 값 변경
    printf("%d\n", a);    // 20
    return 0;
}

`*p = 20;`은 p 자체를 바꾸는 게 아니라 p가 가리키는 곳의 값을 바꾼다. 결과적으로 a가 20이 된다.

핵심 개념 — 포인터 연산자 `*`는 두 가지 역할. ① 선언: `int *p` (포인터 타입 선언) ② 역참조: `*p` (값 접근). 같은 기호지만 맥락이 다르다.

c
// 이중 포인터 (포인터의 포인터)
int a = 5;
int *p = &a;
int **pp = &p;
printf("%d\n", **pp);  // 5  (두 번 역참조)

// 함수 포인터
int add(int a, int b) { return a + b; }
int (*fp)(int, int) = add;
printf("%d\n", fp(3, 4));  // 7

주의 — 초기화하지 않은 포인터(`int *p; *p = 10;`)는 정의되지 않은 동작(Undefined Behavior)이다. 반드시 유효한 주소를 할당한 후 역참조해야 한다.

실기 드릴 2문항
code실기 드릴 · 코드 추적

다음 C 코드의 출력은?

c
#include <stdio.h>
void swap(int *a, int *b) {
    int t = *a;
    *a = *b;
    *b = t;
}
int main() {
    int x = 3, y = 7;
    swap(&x, &y);
    printf("%d,%d", x, y);
    return 0;
}
code실기 드릴 · 코드 추적

다음 C 코드의 출력은?

c
#include <stdio.h>
int main() {
    int a = 10;
    int *p = &a;
    int **pp = &p;
    **pp = 30;
    printf("%d,%d,%d", a, *p, **pp);
    return 0;
}