Proven C Book←↑→

이 책을 읽는 법 — 수준별 학습 경로

이 책이 쓰여진 기준은 앞에서 뒤로 읽는 것이다. 장의 차례가 곧 설명의 차례이고, 뒤의 장은 앞의 장이 세워 둔 어휘와 그림 위에 선다. 그러니 이 책이 스스로 가정한 순서는 그것 하나다.

다만 읽는 사람의 사정은 저마다 다르다. 수준도, 지금 필요한 것도, 이 언어를 쓸 자리도 다르다. 그러니 자기 수준과 용도에 따라 취사선택하면 된다. 처음 배우는 자리라면 기준대로 따라오는 것이 편하고, 이미 C 를 쓰고 있다면 필요한 장과 부를 골라 읽어도 된다. 그 사이에도 여러 수준이 있다 — 다른 언어는 익숙한 사람, 오래전에 배운 것을 다시 세우려는 사람, 임베디드 쪽으로 갈 사람.

아래의 네 갈래는 그런 독자들이 고를 수 있도록 적어 둔 단축 경로다. 그대로 따르라는 것이 아니라, 자기 자리에 가까운 것을 골라 쓰면 된다.

★ 다만 어느 경로를 고르든 덜어 내지 말아야 할 자리가 있다. 제1부와 제2부다.

이 두 부가 이 책에서 가장 중요한 내용이다. 기계가 기억을 어떻게 다루는지, 수와 글자가 어떻게 표현되는지, 번역과 최적화가 무엇을 하는지 — C 의 나머지 전부가 이 두 부에서 다룬 사정 위에 서 있다. 포인터가 왜 그냥 숫자가 아닌지, 정수가 왜 감아 도는지, 컴파일러가 왜 내가 쓴 대로 하지 않는지 — 뒤에서 만날 물음들의 답이 이미 여기에 있다. 그래서 이 두 부를 온전히 아는 것과 아닌 것의 차이가, 뒤의 열한 부를 읽는 내내 벌어진다.

경험이 있는 독자라면 여기 실린 것의 상당 부분을 이미 알 것이다. 그렇더라도 빠뜨린 것이 없는지는 반드시 확인하고 넘어가시라. 훑어 읽되 각 장의 목표와 갈무리를 짚어, 처음 보는 것이나 「알고는 있었지만 왜 그런지는 몰랐던 것」이 나오면 그 장은 제대로 읽는다. 뒤에서 막히는 자리의 뿌리는 대개 이 두 부에서 비어 있던 한 칸이다.

★★ 그리고 무엇을 고르든 하나만 더 기억하면 된다 — 건너뛴 장은 「없는 것」이 아니라 「필요할 때 돌아올 곳」이다. 본문의 #chref 참조가 그 자리를 계속 가리킨다. 단축 경로로 한 바퀴를 돈 뒤에 기준의 순서로 다시 읽으면, 그때는 훨씬 빨리 읽히고 넘겼던 것들이 제자리를 찾는다.

길 ① — 프로그래밍이 처음이다#

이 길은 기준 그대로 — 이 책의 순서다. 골라 낼 것이 없으니, 걸음의 속도만 몇 마디 보탠다.

제1–2부는 코드가 거의 없는 열다섯 장이고, 여기서 지치면 남은 책을 못 읽는다. 이 두 부는 「이해」가 아니라 「낯익음」이 목표다 — 기억에 주소가 있다, 정수는 감긴다, 실수는 근사다, 이 셋만 남으면 충분하다. 나머지는 뒤에서 코드와 함께 다시 온다.

구간무엇에 마음을 쓰나
1–15장 (제1–2부)낯익어지는 것이 목표. 외우지 않는다
16–26장 (제3–5부)★ 여기서부터 손으로 친다. 예제를 그대로 쳐 보고 한 줄씩 바꿔 본다
27–35장 (제6부)정수와 변환 — 이 책에서 처음 만나는 함정 지대
36–46장 (제7부)가장 가파른 구간. 급하면 여기서 한 번 쉬어 간다
47–54장 (제8–9부)구조체와 계약. 「왜 이렇게 정해졌나」가 들리기 시작한다
55–66장 (제10부)프로그램의 바깥 — 링크·이름·전처리기
67–89장 (제11부)읽기보다 찾아 쓰기. 통독하지 않아도 된다
90–100장 (제12부)실물 라이브러리로 앞의 규율을 다시 본다
101–105장 (제13부)실무의 자리와 다음 걸음

표 0.1 — 처음인 사람의 걸음

길 ② — 다른 언어는 안다, C 가 처음이다#

파이썬·자바스크립트·자바처럼 기억을 감춰 주는 언어를 써 온 사람의 길이다. 문법은 빨리 읽히지만, 이 책이 진짜로 주려는 것은 문법이 아니라 기억과 계약이다.

  1. 제1부와 제2부 전부 — 건너뛰지 않는다. 3–5장의 주소와 기억의 갈래가 이 언어의 세계관이고, 6–7장의 감김과 근사에서 다른 언어에서 안 겪던 사고가 나온다. 아는 대목은 빨리 넘기되, 빠뜨린 것이 없는지 확인하면서 지나간다.
  2. 16–26장 — 문법은 빠르게 훑는다.
  3. 36–46장 — ★ 천천히. 포인터·수명·소유가 이 길의 핵심이다.
  4. 53–54장 — 계약과 정의되지 않은 동작. 「런타임이 막아 주지 않는다」의 뜻을 여기서 정확히 안다.
  5. 66장 부터 — 필요할 때 찾아 쓴다.

건너뛰어도 되는 곳: 32–33장 의 제어 흐름 문법. 다만 switch 의 흘러내림(32장)만은 보고 지나간다 — 다른 언어와 다르다.

길 ③ — C 를 쓴 적 있다, 제대로 다시 하고 싶다#

가장 흔한 독자다. 「돌아가는 코드는 쓰는데 왜 그런지는 모른다」를 메우는 길이다.

★ 그래서 이 길은 제1부와 제2부를 먼저 훑는 것으로 시작한다. 「왜 그런지」의 답이 대부분 거기 있기 때문이다. 이미 아는 대목이 많을 테니 빨리 넘기되, 각 장의 목표와 갈무리를 짚어 빠뜨린 것이 없는지 확인한다. 아래 표의 물음들이 흐릿하게 느껴진다면 그 뿌리도 대개 이 두 부에 있다.

아마 흐릿할 것가서 볼 곳
정수 승격과 통상 산술 변환30장 + 부록 C
배열은 왜 포인터가 아닌가40–41장
수명·저장 기간·static 의 두 뜻45·58장
const·volatile·restrict 가 실제로 무엇을 약속하나27·53장
구조체의 패딩과 정렬47–48장
정의되지 않은 동작이 왜 「그냥 크래시」가 아닌가54장
링커가 실제로 하는 일17·56·57장
함수 호출의 안쪽62장
C23 이 바꾼 것부록 G

표 0.2 — 다시 배우는 사람이 먼저 볼 곳

그다음 제12부를 읽는다 — 앞의 규율이 한 라이브러리 안에서 어떻게 함께 서는지를 보는 자리이고, 이 책에서 실무에 가장 가까운 부분이다.

길 ④ — 임베디드·시스템 쪽으로 간다#

기계에 가까운 자리로 갈 사람의 길이다. 제1–2부를 건너뛰지 않는다 — 다른 길에서는 배경인 것이 이 길에서는 본론이다.

  1. 2–5장 — 주소·정렬·기억의 갈래.
  2. 6–11장 — 표현과 인터럽트.
  3. 12–15장 — 캐시와 최적화, 그리고 추상 기계.
  4. 28–30장 — 폭과 변환. 좁은 기계에서 사고가 나는 자리다.
  5. 48·51장 — 비트 관용구와 배치·정렬. 레지스터를 다루는 문법이다.
  6. 49·57장 — 표현을 다시 읽는 법과 호출 규약.
  7. 81·85장 — 비동기와 원자성. volatile 의 진짜 쓰임이 여기 있다.
  8. 88–89장 — 기억 배치와 할당자. 힙이 없는 자리를 포함해서.
  9. 104장 — 도구와 관행.

무엇을 읽지 않아도 되는가#

어느 길에서도, 처음 읽을 때 건너뛰어도 되는 것들을 적어 둔다. 없어서 막히는 자리가 아니라, 필요해질 때 찾아오면 되는 자리다.

반대로, 어느 길에서도 건너뛰지 말 것을 하나만 고르라면 54장 이다. 이 언어에서 가장 비싼 실수들이 전부 그 장에 모여 있다.