C linked list
C 링크드 리스트
May 29, 2026
C 연결 리스트 정리
1. 전체 목표
이 코드는 "HELLO" 를 거꾸로 출력 (OLLEH) 하는 프로그램이다.
핵심 아이디어는 연결 리스트(Linked List) — 쪽지들이 서로 연결된 체인 구조.
2. struct 란?
서로 다른 타입을 하나로 묶는 설계도
struct node { char c; // 글자 한 개 struct node* p; // 다음 쪽지 주소 };
struct 를 쓰는 이유
묶지 않으면:
char c; → 그냥 글자 struct node* p; → 그냥 주소 어떤 글자가 어떤 주소랑 짝인지 알 수 없음
묶으면:
┌──────┬──────┐ │ c │ p │ → 항상 한 세트, 절대 분리 안 됨 └──────┴──────┘
c,p는 갑자기 나온 게 아니라
struct node설계도에서 직접 붙인 이름
n->c,n->p로 접근할 수 있는 이유가 바로 이것
3. 포인터(*) 와 -> 란?
포인터란?
* = 실제 데이터가 아니라 "데이터가 있는 주소(번지수)" struct node → node 자체 (c, p 두 칸짜리 덩어리) struct node* → node 가 있는 곳의 주소 (숫자 하나)
-> 란?
포인터 변수에서 내부 값을 꺼낼 때 사용
(*n).c == n->c // 완전히 같은 의미 (*n).p == n->p
(*n).c → 귀찮으니까 → n->c "이 주소로 찾아가서 c 칸 꺼내줘"
타입이 필요한 이유
주소만 달랑 있으면: 0x7fff5678 ← 여기 가면 뭐가 있어? 알 수가 없음 타입이 있으면: int* → 여기 가면 int 가 있어 char* → 여기 가면 char 가 있어 struct node* → 여기 가면 struct node 가 있어
4. func 함수 — 쪽지 체인 만들기
struct node* func(char* s) { struct node* h = NULL, *n; while(*s) { n = malloc(sizeof(struct node)); n->c = *s++; n->p = h; h = n; } return h; }
반환 타입 struct node* 의 의미
struct node* func(...) ───────────── "node 자체를 반환해" 가 아니라 "node 가 있는 주소를 반환해" 라는 뜻 반환되는 것 = 주소 숫자 하나 (그 주소에 가면 node 구조가 있음)
func 와 struct node 는 다른 것
struct node = 쪽지 한 장의 설계도 (c, p 딱 2칸) func = 쪽지를 만드는 공장 (내부 변수, 반복문 등) func 안에 변수가 많은 건 공장 내부 작업 도구일 뿐 쪽지 구조랑 섞어서 볼 필요 없음
한 줄씩 분해
| 코드 | 설명 |
|---|---|
struct node* h = NULL, *n | h = 체인 맨 앞 주소 / n = 현재 만드는 쪽지 주소 |
n = malloc(sizeof(struct node)) | 설계도 크기만큼 메모리 생성 |
n->c = *s++ | c 칸에 현재 글자 저장 후 다음 글자로 이동 |
n->p = h | p 칸에 기존 체인 주소 저장 |
h = n | h 를 새 쪽지로 갱신 |
return h | 완성된 체인의 맨 앞 주소 반환 |
체인이 만들어지는 과정 ('H', 'E', 'L', 'L', 'O')
1회차 'H' h → ┌──────┬──────┐ │ 'H' │ NULL │ 2회차 'E' h → ┌──────┬──────┐ ┌──────┬──────┐ │ 'E' │ → │ → │ 'H' │ NULL │ 3회차 'L' h → [L] → [E] → [H] → NULL 4회차 'L' h → [L] → [L] → [E] → [H] → NULL 5회차 'O' h → [O] → [L] → [L] → [E] → [H] → NULL
새 쪽지를 항상 앞에 붙이는 것만으로 자동으로 역순이 됨
5. main 함수 — 출력 + 메모리 반납
struct node* n = func("HELLO"); while(n) { putchar(n->c); struct node* t = n; n = n->p; free(t); }
while(n) 이란?
n 이 NULL 이면 → 거짓 → 반복 종료 n 이 주소값이면 → 참 → 반복 계속 "다음 쪽지가 있으면 계속해"
t 가 필요한 이유
// t 없이 이렇게 하면? free(n); // O 삭제 n = n->p; // ??? O 가 이미 삭제됐는데 p 에 접근 불가 → 오류 💥
t 의 역할: "이동하기 전에 현재 위치 백업해뒀다가 이동한 후에 안전하게 삭제"
4번 반복 흐름
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1회차 n → [O→L→L→E→H] putchar → 'O' 출력 t = n (O 백업) n = n->p (L 로 이동) free(t) (O 삭제) 화면: O ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2회차 n → [L→L→E→H] putchar → 'L' 출력 ... 화면: OL ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3회차 화면: OLL 4회차 화면: OLLE 5회차 화면: OLLEH ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ n = NULL → while 종료
6. 전체 흐름 요약
"HELLO" 입력 ↓ func() 가 글자마다 쪽지를 만들되 항상 "앞에 붙이는" 방식으로 체인 구성 ↓ 체인 완성: O → L → L → E → H ↓ 앞에서부터 순서대로 출력 ↓ 결과: OLLEH
7. 핵심 개념 한눈에 보기
| 개념 | 설명 |
|---|---|
struct | 다른 타입을 하나로 묶는 설계도 |
* (포인터) | 실제 데이터가 아닌 데이터의 주소 |
-> | 포인터에서 내부 값에 접근하는 연산자 |
malloc | 메모리 빌리기 (쪽지 생성) |
free | 빌린 메모리 반납 (쪽지 삭제) |
struct node* | node 자체가 아닌 node 의 주소 타입 |
NULL | 아무것도 없음 (체인의 끝 표시) |
Go toor?