Linux Programmer

C언어 공부법과 책추천 (C표준) 본문

컴퓨터 관련/C언어

C언어 공부법과 책추천 (C표준)

sunyzero 2015. 1. 12. 20:25

C언어 공부법과 책추천

마지막 수정일 : 2020-11-16

처음 쓴 날짜 : 2015-01-15


이 글은 C언어를 공부할 때 헤메지 않고 국제 표준인 정종(正種) C언어를 배우는데 도움을 주고자 쓰여졌다.

그러기 위해 알아야 하는 용어나 기반지식들을 살펴보고, 추천 도서인 KNK, K&R에 대해 소개하겠다.

(참고로 여기에서 제시하는 방향이나 책이 올바르고 유일한 진리의 길은 아니다. 이 길은 개인적이고 주관적인 견해가 포함되어있으니 감안하고 보길 바란다.)


2015년을 기점으로 현대 컴퓨팅 환경에서 C언어의 위치는 거의 밑바닥에 존재하는 기초 언어이다.

C언어 뒤에 등장한 프로그래밍 언어들은 C언어 문법체계를 따라했을 정도로 큰 족적을 남기기도 했다.


또한 운영체제(Operating system, 이하 OS)의 설계 및 구현에 사용되었기에 시스템 하부 구조를 배울 때 빠짐없이 등장하는 단골손님이기도 하다.



OS, Network, C languageOS, Network, C language



이런 연유로 C언어는 전자전기기계 관련 이공계열의 제1외국어라는 농담이 있을 정도다.

그래서 대부분 대학교 1~2학년때 C언어를 배우는 경우가 많다.


그렇게 공학 계열 필수 과목 중에 하나지만 C언어를 잘못 배운 사람도 꽤 많은 것 같다. 왜냐하면 신입사원 교육이나 강의, 컨설팅을 가보면 C언어를 엉뚱하게 배운 경우가 상당히 많음을 볼 수 있었다. 비율로 따지면 모 그룹의 신입사원은 80%이상이 학부에서 C언어를 잘못 배운채 입사했었다. 특히 제대로 검증할 수 없는 인터넷 카페나 페북 등과 같은 곳에서 소개하는 나쁜 교재나 잘못된 공부 방법으로 시작한 경우에는 거의 99% 개념을 잘못 잡아서 초급에서 헤매다가 끝내 포기하는 경우가 많은 것 같았다. (인터넷에는 좋은 글도 많지만 틀린 글은 더 많다. 안목이 없는 초보 때는 잘못된 글을 가려낼 수 없다.)


그런고로 이 글은 정통파로 C언어를 배우고자 하는 학생들에게 유용할 것 같다.


C언어를 비유할 때 많은 사람들이 쓰는 말이 "악마는 디테일에 있다(The devil is in the details)"는 격언이다. 이는 언뜻 보면 쉬워보이지만, 제대로 하려면 절대로 쉽지 않다는 뜻이다. C언어가 언뜻 보면 쉬운 이유는 문법의 갯수가 적기 때문이다. C언어 문법만 다루면 100페이지도 안나올 정도다. 게다가 C언어 이후에 나온 Java, C++, C#같은 언어들은 C언어 문법 체계의 영향을 받았기 때문에 if, for, while, until 같은 것들은 모두 공통이다. 그래서 다른 언어를 배운 사람은 C를 배울 때는 문법은 정말 빠르게 뗀다. 그리고 이런 문법의 간결함 때문에 C가 쉽다는 착각에 빠지게 된다.


실제로 C를 배운 적은 없지만 자바를 꽤 잘하는 어떤 지인은 C언어를 1개월 남짓에 뗀 경우가 있었다.(그리고 이거 쉽네...하셨다. 포인터도 쉽네하면서 자신은 천재인 것 같다고 했) C언어로 별그리기, 하노이 타워, 테트리스 같은 수준은 곧 잘해낼 수 있었다. 하지만 딱 거기까지였다. 거기서 다음 단계로 넘어가는데 엄청 걸렸다. 몇몇은 문법 수준인 포인터에서도 포기하지만, 사실상 포인터는 그 다음 단계, 즉 C가 쓰이는 분야인 운영체제, 하드웨어, 네트워크가 짬뽕된 세계로 가는 것에 비하면 새발의 피다.


사실상 C를 포기하는 가장 큰 이유는 C를 배우는 데 필요한 배경 지식인 운영체제, 하드웨어, 네트워킹을 같이 배우지 않기 때문이다. 그러다보니 디테일이 부족해지고, 학습자는 부족한 디테일을 상상력으로 메꾸게 된다. 그 결과로 주화입마나 착각에 빠질 수 밖에 없는 것이다.


예를 들어 C언어가 주로 사용되는 분야인 운영체제나 하드웨어, 네트워킹, 고성능 쪽을 생각해보자. 네트워크 데이터 처리만 하려고 해도 endian이나 XDR의 디테일을 알아야 하는데, 이건 C언어 문법에서 다루는 내용이 아니다. 하지만 이런 배경을 모르고 C문법만 배운 수준으로 코드를 짜면 심각한 버그를 만들 가능성이 높다. 또 다른 예로 C에서 Thread를 다루게 되면 CPU의 cache 구조도 알아야 하고, 운영체제, 라이브러리에서 메모리를 관리하는 방법인 page, segment도 알아야 하는 경우가 생긴다. 워낙 안전(safety)과는 거리가 먼 언어라서 디테일 지식이 없으면 꼭 문제를 일으키게 된다.


C언어가 이렇게 된 이유는 C언어의 아버지인 Dennis Ritchie나 동료들인 Ken, Brian (UNIX 주인공들)은 애초에 저런 지식들을 다 아는 프로들이라 굳이 설명할 필요가 없었을 수도 있다. 즉 C언어는 애초에 연구자나 학자들을 위해 만든거라 그런거다.(C언어의 역사를 꼭 찾아보자)


그래서 반대로 C언어를 전혀 쓰지 않는 분야로 진출할거면 굳이 배워야 할 필요가 없다. 간혹 C언어를 배워야 컴퓨터를 제대로 하는 것처럼 강요하는 분위기가 있는데, 그건 90년대, 2000년대 초반에나 통하는 이야기이고, 지금은 전혀 그럴 필요가 없다. C를 쓰지 않는 분야라면 배우지 않아도 괜찮다. 굳이 쓰지도 않는데 C를 배우는데 많은 시간을 버리지 않도록 하자. 게다가 C를 제대로 알려주는 책도 별로 없기 때문에 정말 시간만 버리는 케이스가 될 가능성이 높기 때문이다.



* 본질을 다루기 전에 문제 제기부터 다시 해보자.


C언어를 제대로 배우지 못했다는 것은 구체적으로 어떤 것을 말하는 것일까? 아래 질문에 답을 하거나 개념이라도 확실히 알고 있다면 C언어를 제대로 배운 것이고 아니라면 기초가 부실하거나 잘못 배운 것이다. (아래 질문들의 절반도 모르겠다면 C언어를 제대로 배운 것이라고 할 수 없다)


질문0. C언어는 언제, 어디서, 누가, 무엇을 위해 만들었는가?

질문1. C언어 국제표준(ISO/IEC 9899)은 무엇이며 C99, C11은 무엇인가?

질문2. C언어의 stdio(표준입출력)는 왜 만들어졌는가?

질문3. 전처리기(preprocessor)가 하는 일은 무엇인가? 그리고 왜 만들어졌는가?

질문4. long, int, short, pointer 변수의 크기는 몇 bit인가? (이들 크기는 고정 사이즈가 아님. int는 32bit라고 단정하면 틀린 거다)

질문5. API와 ABI는 무엇인가?

질문6. 오브젝트(object)란 무엇인가? (객체지향의 오브젝트를 말하는 것이 아님)

질문7. 링커(linker)가 하는 일은 무엇인가?

질문8. call-by-reference, call-by-value란 무엇인가? (C에 왜 call-by-reference가 없는지 설명할 수 있어야 함)

질문9. C언어의 main 함수의 return 값은 왜 int 인가? (void main()으로 선언하면 왜 틀리는가?)

질문10. C언어와 C++은 다른 하나가 부분집합인 서브셋인가? 아니면 둘은 다른 언어인가?

질문11. 하드웨어 제어에 C언어가 사용되는 이유는 무엇인가?

질문12. 시퀀스 포인트(sequence point)가 무엇인가?

질문13. Side effect란 무엇인가?

질문14. UB(Undefined behavior)란 무엇인가?


그럼 질문은 끝내고 C언어의 특징을 생각해보자.

원래 C언어는 구구단이나 별그리기를 하려고 만든 언어는 아니다. 물론 문법을 배우는 와중에 구구단을 짤 수도 있다.  하지만 구구단 작성법을 배우는게 C언어의 본질적인 공부는 아니라는 것이다.


C언어는 low level과 memory, 운영체제(OS) 등을 이해하거나 작성하기 위해 거쳐가는 관문이 C언어의 본질이다. 구구단 같은 수치 연산이나 논리 연산을 배우는 것이 주목적이라면 python이 백배 낫다고 생각된다. 사실 비전공자라면 굳이 C언어를 배울 필요가 없다. 오히려 C언어 대신에 python을 공부하는게 훨씬 도움이 된다. 

왜냐하면 C언어는 문법은 간결하지만 그 대신에 함정이 많은 구조를 가지고 있어서 제대로 공부하지 않으면 이런 함정에서 허우적 대기 십상이다. 문법만 대충 나열한 책들은 정통파 C언어를 제대로 다루지 않기 때문에 더더욱 함정에 빠질 가능성이 높다.


비비꼬아 놓은 C언어 문제풀이 학습지 책이나 암기문제를 다루는 책은 성취가 점수로 표시되니 뿌듯할 수도 있다. 하지만 이는 사파의 무공과 같아서 운영체제(OS)라는 본질의 첫 단추를 끼울때 방해가 될 수도 있다. 무슨 올림피아드 대회 준비 같은 것이 아니라면 이런 이단 사이비 공부에 심취하지 않는 편이 좋다. 특히 연산자 우선 순위를 비비 꼬아 놓거나, 포인터를 스크류바처럼 꼬아놓은 문제들을 수두룩하게 풀고 있다면 이미 이단 사이비에 빠진 것이니 조심하자.

(아래는 The International Obfuscated C Code Contest 코드이다. 이런 것은 정통파 배움과는 차이가 있다.)


The International Obfuscated C Code Contest - garry.c (1995)The International Obfuscated C Code Contest - garry.c (1995)


물론 어떤 길로 가든지간에 최고봉에 오르면 다 부질없기는 하다. 이 글에서 제시하는 방법이 아닌 길로 갔어도 최고봉에 오르는 사람들도 많다. 하지만 최고봉에 오르기 위해 정통파로 오르는 것과 비정통으로 오르는 것에는 약간의 차이가 있다.(특히 걸리는 시간과 시행착오 횟수가 크게 달라질 수 있다.)




C언어를 배우기 전의 기본 지식 (이 정도는 알아야 면장이라도 해먹는다.)


차례

1. C언어란 무엇인가?

2. C언어 표준 문법

3. C언어를 공부하는 방법

3.1. C표준 문서로 공부할까?

3.2. 구*, 네*버 검색으로 시작할까?

3.3. IT학원

3.4. 독학

3.5. 그럼 어떻게 배워야 하나?

4. 검증된 C언어 책은 무엇이 있는가?

5. C언어 개발환경 선택

5.1. gcc

5.2. LLVM의 clang

5.3. 비주얼 스튜디오

6. 결론



1. C언어란 무엇인가?

C언어는 1972년도에 UNIX 운영체제(OS)의 assembly 코드 작성을 줄이기 위해 개발된 고급언어이다. 운영체제 작성을 위해 개발되다보니 운영체제의 기본적 이념과 언어적 특징이 섞여있다. 이런 연유로 운영체제를 배울때 가장 중요한 것중 하나가 C언어에 대한 이해도이다. (초기 UNIX는 Ken Thompson이 assembly로 개발했으며 이 후 UNIX 코드의 대부분은 C언어로 재작성되었다.)


C언어는 AT&T Bell labs.의 Dennis Ritchie가 Ken Thompson, Brian Kernighan과 만들었고, 1989년도에 ANSI C 승인을 받았다.


** 켄 톰슨, 데니스 리치, 브라이언 커니한이 누군지 꼭 기억하고 알아보자.(여기에 더해 Bill Joy, Richard Stallman도 알아두면 좋다.)

이들을 듣보잡 따위, 이름따위라고 치부하면 앞으로 크게 되기 힘들다.



2. C언어 표준 문법

C언어에도 국제 표준이 있나?[1]

=> 그렇다. 현재 쓰이는 것은 C99, C11 버전이 있다. (C99는 1999년도 표준, C11은 2011년도 표준)

==> 오래된 표준인 ANSI C는 C89이며 2015년을 기준으로 하면 26년이나 지난 너무 옛날 버전이다. 표준 제정 이전까지 생각하면 30년도 훌쩍 넘은 옛날 버전이다. 2015년을 기준으로 하면 가장 많이 쓰이는 표준은 C99이므로 C99 표준에 맞춰서 배우는 것이 좋다. 심지어 최근의 clang 컴파일러는 기본 문법이 C99로 바뀌었다.


표준이 아닌 내용도 있나?

=> 그렇다. C언어는 특히 표준이 느슨해서 비표준도 많은 편이다. 일례로 GCC의 확장기능, 비주얼 스튜디오의 C 확장 기능이 있다. 이들 중에는 UB(Undefined Behavior), IB(Implementation defined Behavior) 같은 것으로 분류되는 부분도 있다.


책에 나온 내용은 전부 C표준 문법인가?

=> 아니다. 아쉽게도 C표준 문법을 지키지 않는 책들도 많다. 그런 책들은 문제풀이식, 속성 암기식을 지향한다. 

그래서 본인은 문제풀이식, 혹은 너무 쉬운 것만을 강조하는 그림 책 수준의 C언어 교재는 추천하지 않는 편이다. 심지어 그림으로 쉽게 풀어쓴 책들의 그림이나 비유 및 표현은 잘못된 경우가 많았다.


표준을 지키지 않으면 어떤 문제가 있나?

=> 사고가 발생할 수 있다. 예로 회사에서 컴파일러를 변경했다면 비표준으로 작성해왔던 습관은 큰 사고를 일으킬 가능성이 있다. (돈을 다루는 곳이라면 매우 심각한 문제가 된다)

==> 비표준을 쓰더라도 비표준과 표준의 차이를 알고 쓰거나, 안전하게 conditional directive를 설정해뒀다면 괜찮다. (실제로 중상급 이상이 되면 비표준과 표준을 자유롭게 쓰면서 UB나 IB를 구분할 수 있는 레벨이 된다)

   그러나 비표준인지 혹은 UB인지도 모르면서 되는대로 마구 써대면 곤란하다.

   따라서 일정 레벨(중상급이상?)을 넘어가기 전까지는 표준에 익숙해지도록 노력하는 것이 좋다. 언어를 배울때 표준어부터 배우지, 욕설이나 비속어, 방언부터 배우지 않는 것과 같다. 미국인이 한글을 비속어,은어로 배워서 공식 석상에서 "방가방가~ XX놈들아" 이렇게 연설한다고 생각해보자. 한마디로 끔찍하다. 하지만 한국어에 대해서 체계적으로 배우고, 활용하게 되면서 경험이 쌓이면 공식 석상에서 사용하는 표준어와 비공식적인 자리에서 사용하는 비표준어, 비속어의 차이에 대해 잘 알게 되는 것과 같다.



3. C언어를 공부하는 방법


3.1. C표준 문서로 공부할까? = 비추천

C표준은 레퍼런스로 사용되는 것이므로 학습용 교재는 아니다. 굳이 비교하자면 영어사전같은 느낌? 영어 사전으로 단어를 주구장창 외울 수는 있겠지만 굳이 그런 방식으로 공부하는게 효율적일까? 참고로 아래는 C 표준 문서이다. 이걸로 공부하기는 쉽지 않다. 그래서 교재가 필요한 법이다.


C11 표준 문서C11 표준 문서



3.2. 구*, 네*버 검색으로 시작할까? = 비추천

인터넷은 정보의 바다!!! 룰루랄라~~~ 이렇게 시작하는 것이 바로 최악이다.


이건 검색을 아예 하지 말라는 소리가 아니다. 어느 정도 기초를 잡기 전에 검색만으로 해결하려는 습관을 들이지 말라는 것이다. goog**이나 nav**에는 있는 내용은 2가지의 큰 문제가 있다.


첫째는 인터넷의 블로그나 지식검색의 내용이 올바른지 누가 보장 해줄 수 있느냐는 것이다.

물론 고수들의 블로그나 검증된 사이트의 문서(예를 들어 ibm developerworks)는 대부분 오류가 없다. 하지만 고수들의 블로그나 검증된 사이트에는 아쉽게도 초급 내용은 별로 없다.

그래서 아이러니 하게도 인터넷 지식은 고급 내용일수록 오류가 적고, 초급 내용일수록 오류가 많다.


둘째로 블로그나 지식검색의 있는 내용은 조각난 지식들이다.

이들은 국소적인 내용을 다루는 경우가 많기 때문에 중급 레벨이 되어 참고용으로 볼 때는 가려운 곳을 긁어주듯이 좋을 수 있다. 하지만 기초가 없을때 검색으로 공부를 시작하면 체계가 없는 사상누각이 될 가능성이 높아진다. 결국 크리티컬한 사고를 치는 사람이 될 가능성이 높아진다.


Internet KnowledgeInternet Knowledge


용산에 가면 다양한 곳에서 컴퓨터 부품을 팔지만 모르는 사람은 뒤통수 맞기 십상이다. 인터넷도 안목이 생긴 뒤에는 정보의 바다지만 안목이 없을때는 잘못된 내용을 배울 수도 있다.



3.3. IT학원 = 복불복

학원은 복불복이다.


학원에 가서 공부한 사람 중에는 의외로 제대로 배워온 사람도 있고, 그렇지 않은 사람도 있다. 한때는 비트컴퓨터학원은 꽤 믿을 수 있다고도 했었다.(지금은 예전에 비하면...음...)


사실 어느 정도 기본기가 있다면 학원에 가도 무방하다. 어차피 학교에서 배운 내용을 바탕으로 틀린 내용을 걸러낼 수도 있으니까. 하지만 생판 초짜일 때 학원에 가면 잘못된 내용을 검증할 기초 지식이 없기 때문에, 잘못된 강사를 만나게 되면 요상한 내용만 배워올 수도 있다. 게다가 나쁜 코딩 습관은 덤이다.


물론 제대로 된 강사를 만나면 대박이겠지만... 이쯤 되면 확률에 맡기는 로또가 된다.

(이건 대학도 마찬가지다. 좋은 교수를 만나면 대박이지만 엉터리 교수를 만나면 요상한 내용을 배울 수 있다. 그래서 학습자는 되도록이면 많은 교습자를 만나고, 많은 책을 읽는 것이 좋다고 생각된다.)


그래서 IT학원은 복불복이다.



3.4. 독학 = 비추천

독학으로 배운 사람들의 특징은 이해하지 못한 내용을 상상으로 메꾼다는 점이다.

물론 매우 스마트한 사람은 독학으로도 대성할 수 있다.

하지만 나는 예외적인 상황을 소개하려는 것이 아니다.


간혹 독학해도 성공할 수 있다면서 독학으로 성공한 유명 프로그래머, 블로거의 이름을 대는 학생들이 있다.

그러면 나는 되묻는다 "본인이 그 사람들만큼 스마트한가?"라고...

여기서 Yes라고 할 수 있다면 독학해라.

하지만 그렇지 않다면 누군가의 도움을 받아라. 그게 현명한 선택이다.

(독학으로 높은 수준에 오른 사람들은 독학을 했든 누군가에게 배웠든 어쨌든 스마트한 머리로 잘 할 수 있는 사람들이다. 그 사람들과 비슷한 레벨이 아닌데 평범한 사람이 그 사람이 했던 방식을 따라하면 실패할 가능성도 높다.)



3.5. 그럼 어떻게 배워야 하나?

상책(上策)은 고수한테 직접 배우는 것이다.

대학교라면 뛰어난 교수 밑에서 공부하거나 뛰어난 선배 그룹에서 낑겨 들어가 배우는 거다.

(하지만 굇수가 도사리고 있는 랩에 잘못 들어가면 개고생만 하고 공부는 ㅠㅠ)


대학교라면 학교에 평판이 좋고 실력도 좋은 랩이 있을거다. 조금만 알아보면 분명히 찾을 수 있다.

학부생이라고 하더라도 방학때든 학기때든 랩에 잔심부름이라도 하면서 공부하겠다고 하면 내치는 교수님은 없다. 내친다고 하더라도 열 번 찍어 안넘어 가는 교수님은 없으니 계속 시도해보길 권장한다.


좀 큰 회사라면 사내에 소문난 고수가 한 두명은 꼭 있다.

아부를 하던 선물 공세를 하던지 인맥을 터서 도제식 교육을 받는 것도 좋다.

고수에게 일주일에 1시간이라도 핵심 원포인트 레슨을 받는다면 크게 실력이 늘 수 있다.


하다못해 잡담을 하다가도 고수에겐 중요한 키워드를 얻을 수 있고, 풀리지 않는 질문을 하면 결정적인 원포인트를 받게 된다. 개인적인 견해지만 고수에게 받은 1시간 원포인트 레슨은 적어도 100시간의 삽질을 줄여준다고 생각한다.


중책은 좋은 커뮤니티의 오프모임을 이용하는 것이다.

자세히 뒤져보면 꽤 좋은 오프 스터디 그룹이 있다.

커널이든지 리눅스든지 열심히 조사해봐라.

거기가서 바닥부터 다지면 큰 도움을 받을 수 있을 것이다.


하책은 어쩔 수 없이 독학, 학원이다.

그 대신에 좋은 책(KNK)으로 시작해야 한다.

주변에 대충 물어보고 "OO책 좋냐? 쉽냐?", 혹은 네이버에 "C언어책 추천"으로 검색해서 C언어 책을 사면 실패할 가능성이 매우 높다. 특히 초급자들끼리 서로 추천해주는 책은 믿지 않는 것이 좋다. (실제로 모 코딩관련 카페에서 추천도서로 올려진 책 목록 중에 거의 대부분은 비표준이 남발되는 좋지 않은 책이었다.)


예를 들어 초급자들은 라면스프로 맛을 낸 것과 핸드메이드로 맛을 우려낸 차이를 알지 못한다. 

그렇다고 해서 요리책에서 초급자들은 맛을 잘 모르니 라면스프를 쓰라고 가르치는게 올바른 책은 아니지 않는가?

책 추천도 마찬가지다. 재밌고 신나지만 틀린 내용이나 편법을 가르쳐주는 책으로 배워봐야 무슨 소용인가?


고수들의 세계에서는 서로 몇 다리 건너면 알만한 사람들이 많아서 공개적으로 디스를 하지 못한다.

하지만 왠만한 고수분들은 다 안다. 추천을 많이 받는 쉬운 책들 중에 함정이 많다는 것을...


간혹 국제 표준 준수보다 쉽고 신나게 배우는게 중요하므로 표준은 무시해도 된다고 말하는 사람도 있다. 물론 그 말이 맞을 수도 있다. 간혹 표준을 무시하고 야매로 배웠지만 후일 올바른 표준을 다시 배워서 옳은 길로 가는 사람도 있다. 하지만 예외적인 케이스를 보고 그것이 옳다고 믿는 것은 좋은 태도가 아니다.


모든 배움에는 단계와 규칙이 있다. 그것을 무시해도 성공하는 돌연변이들이 있지만 그것을 일반화하는 것은 또다른 오류다.


논문을 써본 사람들은 알겠지만 학회는 논문의 작성 규약, 환경 제약, 리뷰 조건 등을 타이트하게 설정한다. 자연과학에서는 시약조차도 특정 브랜드를 사용하도록 규제할 수도 있다. 초보자들에게 이런 규약은 굉장히 불편해 보이지만 시간이 지나 전문가가 되면 굉장히 합리적인 규칙이라고 생각을 고쳐먹게 된다.


왜냐하면 저런 규약들은 논문의 재현성을 보장하기 때문이다. 프로그래밍에 있어 표준도 바로 그런 존재다. 표준을 준수하면 내가 작성한 코드는 다른 플랫폼에서도 동일한 작동을 보장할 수 있다. 그때 그때 다르게 작동하거나 플랫폼이 다르면 컴파일이 실패할 수도 있는 코드는 올바른 코드도 아닐뿐더러 나중에 같이 일하는 사람들이 해당 버그 때문에 고생할 수도 있다. (실제로 표준을 잘 모르는 사람과 일을 하면 의외의 버그를 만들어 피곤한 일들이 많이 생기고, 전문가들은 점점 그런 사람을 기피하게 된다. 표준을 지키지 않는 사람은 컨벤션도 거의 무시하거나 고집만 쎈 경향이 짙다.)


물론 절대로 타인과 같이 일하지 않고 그냥 내 컴퓨터에서 고독하게 코딩을 통해 정신 수련을 하겠다면 표준따위 무시해도 상관없을지 모른다. 그러나 그런 것이 아니라면 국제 표준에 대해 이해하는 것은 매우 중요하다.


다시 한번 말하지만 비전공자이며 low level을 배울 필요가 없다면 되도록이면 C언어를 배우지 않는 방향으로 공부하는게 좋다. 왜냐하면 C언어는 문법은 쉽지만 문법 구조에 함정이 많은 스타일이기 때문이다. 따라서 초급에서 C언어 문법을 배우기는 쉽지만, 초급에서 탈피하려면 언어적인 함정을 피해가는 방법과 OS 레벨, 하드웨어 레벨의 지식을 같이 배워야 하기 때문에 제대로 배우는게 쉽지 않다.


비전공자, 그것도 처음 시작하는 사람에게 C언어를 추천하는 사람이 있다면 아마도 구렁텅이에 빠트리려고 하는 행동인지 의심해봐라. 혹은 본인도 추천하는 행동의 결과가 뭔지도 모르는 레벨이거나...


Tip!


C언어에는 많은 사람들이 어렵다고 생각하는 포인터(pointer)가 있다. 사실 포인터 개념은 매우 직관적이라, 어려운 것은 아니다. 하지만 이상한 C언어 책들이 포인터를 미친듯이 꼬아서 가르치기 때문에 오히려 더 어렵게 포장되어 있다. 그리고 이런 이상한 책들은 포인터를 떼면 마치 C언어를 정복한 것처럼 호도하고 있다. 그러나 절대로 아니다.


포인터를 떼봐야 C언어 문법을 이제 막 뗀 초급자이다. C언어 포인터도 모른다면 아직 문법도 못뗀 상태이다. 그리고 포인터는 뒤에 운영체제론을 배워서 physical memory와 page, segment들이 어떻게 맵핑되는지 공부해야 내부 구조가 더 잘 이해된다. 


따라서 엉성하게 포인터를 비비꼬아 놓은 책을 보지 말고, 차라리 나중에 운영체제론을 배울때 그 연관성에 대해서 공부하는게 낫다. 가끔보면 학생들 중에 서너개씩 중첩된 포인터 문제를 풀면서 머리를 쥐어뜬는 있는 경우를 볼 수 있는데, 쓸데없는 일이다.


4. 검증된 C언어 책은 무엇이 있는가?

KNK, K&R이 검증된 책이다. 그 중에서 KNK로 시작한 뒤에 다른 책을 보는 것이 좋다. 책 이름중에 KNK, K&R은 저자의 이름에서 유래한다. KNK는 K.N.King이고 K&R은 Kernighan & Ritchie에서 유래한다. 아래 그림이 바로 그 책이다.


C언어 책 - KNK(좌) K&R(우)C언어 책 - KNK(좌) K&R(우)


4.1. KNK

KNK의 서명은 C Programming : A Modern Approach이며 C언어 표준에 입각해서 쓰여진 책이다. 이 책은 전세계의 다양한 고수들에 의해서 검증된 책이다. 현재 2판이 나와있으며 가장 많이 쓰이는 C99(1999년 표준)에 입각해서 쓰여져 있다. 책 표지 우측상단에 보면 "Covers both C89 and C99"라고 쓰여있는 것을 볼 수 있다.


KNK의 장점은 표준을 준수하면서 예제로 자료구조의 내용을 조금 포함하고 있다는 점이다. 예제도 상당히 잘 짜여져 있어서 따라하기에도 좋다. 그림과 도식도 이론적으로 틀린 부분이 없다.


* K.N.King : http://knking.com


C언어 입문서로는 KNK만한 것이 없으므로 입문을 제대로 해보고 싶다면 KNK로 시작하는 것을 추천한다. 


2018년을 기준으로 KNK의 번역서는 없다. 하지만 영어가 어렵게 쓰이지 않았으므로 공개된 페이지를 미리 읽어봐서 해석 가능한지 확인해보는 것도 좋다.


4.2. K&R (TCPL)

K&R의 서명은 The C Programming Language이며 C언어의 창시자인 데니스 리치(Dennis Ritchie)와 브라이언 커니한(Brian Kernighan)이 저술한 책이다. (책 제목의 앞글자를 따서 TCPL이라고도 부른다.)

ANSI C(1989년 이전 규칙)의 구식 내용이지만, 짧은 내용 속에 나와있는 예제, 연습문제들이 초기 C언어의 설계철학을 담고 있다.


KNK로 기본기를 다진 뒤에 K&R을 읽고나면 자신도 모르는 사이에 C언어 철학을 이해하게 된다. 참고로 K&R은 공부를 한다기보다는 읽으면서 행간에 함의하고 있는 뜻이 무엇인지를 생각해야 한다. K&R은 설명이 장황하거나 많지 않기 때문에 입문용은 아니고, 오히려 이 책을 읽으면서 막힘이 없다면 C언어의 초급 딱지를 뗄만하다는 것으로 이해하면 좋다.

(K&R의 내용만 보면 지금 컴퓨팅 환경과는 많이 다르기 때문에 그대로 적용한다는 생각은 버려야 한다. 오히려 현시점에서 K&R 방식으로 코딩하면 선임에게 혼날 수 있다.)


이 두 책을 읽고 난뒤에 다른 C언어 사파무공책을 보면 장단점이 잘 보일 것이다.

다른 책의 장단점이 보이기 시작한다는 것은 본인의 정종내공이 깊어져서 안목이 높아진 것을 반증한다.


참고로 고수 세계에서는 이 두 책을 보지 않은 C 프로그래머를 신뢰하지 않는 사람들도 많다. 왜 그런지는 책을 통독해보면 자연스럽게 알게된다.


그리고 다른 책을 보다보면 꼭 명심해야 할 것이 있다.

어떤 책이든 틀린 부분이 있을 수 있다. 하지만 많은 고수가 검증한 책은 대체적으로 틀린 부분이 적은 편이다.

네이버, 다음 같은 포털에서 추천평이 많거나 베스트셀러라고 좋은 책이라는 보장은 없다. 오히려 국내서 중에 C언어 베스트셀러 책은 문제가 많았다. 비유가 잘못된 경우도 많았고, 내용 자체가 표준을 위반하거나 잘못된 경우도 많았다. 잘못된 경우가 한두개가 아니라 꽤 많기 때문에 큰 문제가 있다.


일단 C99가 무엇인지 소개하지 않거나 C표준이 생긴 이유와 역사가 없는 책은 좋지 않은 책일 가능성이 높다.


= 결론 : 검증된 책으로 공부해야 한다. 인터넷 댓글, 동아리 선배가 추천한 책보다 고수들에게 검증된 책을 믿자. 

물론 필자의 글도 의심해볼 수 있다. 의심하면서 KNK 책과 C표준에 대해 의심하고 조사한다면 더욱 좋다. 그렇게 의심이 많은 사람일수록 진리에 접근할 가능성이 높아진다.

== 위의 책만 읽으면 C언어를 끝내는 것이 아니라 올바르게 시작했다는 것을 말한다. 

C언어를 제대로 숙련시킬려면 최소한 대여섯권 이상의 책을 봐야 한다. (최소한 대여섯권이다. 제대로 배울려면 10권이상 봐야 한다.)

위의 책을 정독하고나면 나쁜 책을 골라낼 수 있으니 그 다음은 여러 책을 보면서 틀린 점을 찾아내는 것도 좋은 경험이다.



4.3. C Primer Plus

이 외에 KNK를 구할 수 없을 경우 대체 가능한 입문서로서 C Primer Plus (6th Edition)도 있다. 이 책도 C99 표준과 C언어의 역사, 표준의 필요성들을 소개하고 있으며 C11도 일부 소개하고 있다. 책 내용에서 비표준을 남발하는 경우도 없다. 


다만 예제 코드에 몇몇 빠진 부분이 존재하므로 컴파일 에러가 발생하는 경우라면 출판사에서 제공하는 원래 예제 소스 파일을 받아서 비교해보는 것이 좋다. (예제 코드의 빠진 부분은 원서와 번역서 모두 같다)


그리고 이 책은 번역서가 존재한다. 번역서의 제목은 "C 기초 플러스"이다. KNK 원서를 보기 힘들다면 이 책을 추천한다. 

번역서를 살펴본 결과 번역의 품질은 평범한 수준이고, 좋다고 할 정도는 아니다. (IT업계에서 왠만하면 원서를 보는 것이 좋다는 것이 여기서도 나타난다. 그리고 원서를 보는 연습을 해두면 장기적으로 큰 도움이 될 수 있다.)


C Primer Plus 6th EditionC Primer Plus 6th Edition



4.4. C : A Reference manual

만일 KNK나 C Primer Plus를 보고 좀 부족하다 싶으면 Harbison & Steele 의 C : A Reference manual. (Prentice hall)을 보는 것도 좋다. 이 책은 정리하는 목적으로 보는 경우가 많다. (이 책도 번역본이 존재한다.)


C : A Reference manual. 5th Ed.C : A Reference manual. 5th Ed.



4.5. Computer Systems A Programmer's Perspective

중급 도서 추천을 요청하는 연락이 종종 있어서 또 하나의 책을 추가하도록 하겠다. 사실 입문 레벨의 C언어 공부법을 추천하는 이 글에서 중급 서적, 그것도 운영체제와 관련이 깊은 책을 소개하는게 맞는지는 모르겠으나, 일단 소개를 하도록 하겠다. 하지만 책을 사기 전에 먼저 도서관에서 살펴보고 어느 정도 레벨인지 확인하고 구입하면 좋을 것 같다.


앞에서 언급했듯이 C언어의 본래 목적은 운영체제(OS)와 관련이 깊기 때문에 중급이상의 부분을 공부하려면 필히 컴퓨터 시스템이라는 종착역에 가까워지게 된다. 이를 위해 OS(Operating system)나 CA(Computer Architecture), CS 과목을 공부해야 하는데, OS나 CA는 코드 구현부분보다는 추상적인 개념을 중시하므로 C언어의 원리에 대해 공부할 때는 CS(Computer system)로 공부하는게 낫다.


CS에서 많이 쓰이는 책으로는 CSAPP라고 불리는 Computer Systems : A Programmer's Perspective, Randal E. Bryan의 책이 보기가 편하다. 이 책은 번역판이 있으므로 접근성도 괜찮다고 생각된다. (번역의 질은 평균 이상이다.)


CSAPPComputer Systems A Programmer's Perspective by Bryant and O'hallaron


CSAPP는 OS와 CA의 내용이 조금씩 소개되면서 C언어로 구현된 부분도 소개하고 있다. 만일 읽다가 이해가 가지 않는다면 OS, CA와 연계된 내용일 가능성이 있으므로 조급해 할 필요는 없다. 나중에 OS, CA를 같이 공부하다보면 각각의 과목들과 연결되어있는 부분이 자연스럽게 이해될 수 있기 때문이다.



5. C언어 개발환경 선택

이제 공부할 방법과 책이 선정되었다면 개발 환경을 선택해야 한다.

C언어를 처음 배운다면 컴파일러는 gcc나 LLVM의 clang을 직접 사용하는 방향으로 시작하는 것이 낫다. IDE 통합 개발 환경을 사용하는 것은 나중에 하는 것이 좋다. 특히 컴파일러를 직접 명령행에서 타이핑해서 실행하는 경험은 매우 중요한데, 이는 C언어 뿐만 아니라 대부분의 언어들이 작동하는 방식, 즉 프리프로세싱, 컴파일, 링킹이 어떻게 작동하는 이해하는데 중요한 경험이 되기 때문이다.


만일 처음부터 IDE 환경으로 배우면 IDE 환경이 없을 때는 아무것도 못하고, F5만 누르면 뭐든 뚝딱 만들어내는데 그게 왜 되는지 이해하지 못하기도 한다. 특히 비주얼 스튜디오(Visual Studio)는 매우 좋은 툴이지만 초급딱지를 떼고나서 C++이나 C#을 배울때 사용하는 편이 좋다.


특히 컴파일러, 링커, 편집기, 빌드툴, 디버거는 원래 별개의 프로그램인데, IDE로 시작해서 배우면 이들의 경계를 잘 몰라서 나중에 개념적으로 혼란을 겪는 경우가 많다. 그래서 기초를 중시하는 교수님은 비주얼 스튜디오를 설치하는 경우에도 메모장에서 소스 코드를 타이핑해서 명령행으로 컴파일하는 것을 가르쳐주는 경우도 있었다.


5.1. gcc

GNU의 C컴파일러이다. 표준을 잘 지키는 편이다.

비표준의 편리한 기능을 제공하는데, GCC의 비표준 기능은 역으로 표준에 흡수되기도 했다.

= Linux, UNIX, Windows 등 다양한 곳에서 사용되므로 여러 운영체제에서 프로그래밍 할 때 혼란을 겪지 않는다.

= MS윈도에서 해야만 한다면 VMware나 Virtualbox에 설치해보는 것이 더 좋다. (cygwin도 있긴 하지만 추천하지는 않는다.)


Intel 컴파일러(icc)도 좋지만 상용이다. 하지만 회사는 성능을 위해서 icc를 사용하는 곳도 많다.


5.2. LLVM의 clang

표준도 잘 지키고 최신 컴파일러 기능도 있다.

= Mac OSX에 탑재된 컴파일러가 LLVM기반의 clang이다. 요샌 Linux에서도 많이 쓰인다.


5.3. 비주얼 스튜디오 (비추천)

비주얼 스튜디오의 VC++은 C++ 기반이라서 C와 C++ 중 어떤 기능을 사용하는지 헷갈릴 수 있고 비표준도 많다. 

특히 C++ 기반이라서 C99문법 중 일부분을 지원하지 못한다. (VC++은 2016년 기준으로 아직도 C99 표준을 지원하지 못한다.)


물론 중급자는 VC++을 사용하더라도 이런 차이를 혼동하지 않는다. 하지만 초급자에겐 큰 혼란을 준다. 이는 다른 플랫폼으로 전환할 때도 혼란을 겪게 한다.


간혹 C++은 플러스가 2개나 붙었으니 C의 모든 기능을 포함하는 것이 아니냐고 묻는 사람들도 있다. (그럼 C#은 +가 4개나 되는데 C, C++을 모두 포함하나???)


C++이 탄생되던 시기에는 분명 ANSI-C와 옛날 문법 체계를 포함했었다. 1970~80년대 초반에 C언어의 유행은 너무나 대단해서 C++이 C의 문법체계를 수용하는 것이 유리했기 때문이었다. 그러나 1999년에 승인된 C99 표준 이후로는 둘(C++, C)은 결별하여 다른 언어가 되었다. 게다가 1999년 C99로부터 12년 뒤에 발표된 C11 (2011년도 표준)에서는 C++과는 점점 더 다른 길을 걷고 있다. 물론 공통 분모가 되는 비슷한 부분은 꽤 많지만, 틀린 부분도 꽤 많기 때문에 이젠 둘의 차이를 정확하게 인식해야 실수하지 않을 수 있다.


아직도 C++이 C의 수퍼셋이라고 한다면 20년도 넘은 옛날 지식을 업데이트하지 않은 것이다. 이젠 더이상 C++은 C 표준을 포함하지 않는다. 다시 말해 C++은 C의 수퍼셋이 아니다. (다른 말로 하면 C는 C++의 서브셋이 아니다.) 둘의 차이는 아래 링크의 글을 읽어보도록 하자.


Incompatibilties Between ISO C and ISO C++

https://cinsk.github.io//iso-c-diff-iso-c++/index.html



6. 결론

6.1. C언어는 이공계열의 제1외국어 같은 녀석이다. 이공계열 전공자라면 꼭 배워야만 한다. (비전공자라면 오히려 배우지 않아도 된다.)

6.2. C언어책은 KNK (or C Primer Plus)로 시작하고 K&R로 끝맺는 것이 좋다. 그러나 이것이 끝이 아니라 시작임을 알아야 한다.

     그리고 이왕이면 Harbison & Steele의 C A reference manual도 보는 것이 좋다.

     (C99 국제표준, 그리고 C와 C++의 차이점을 자세히 다루지 않는 책은 던져버리는 것이 좋다. 그런 책은 저자가 정통으로 배우지 않은 경우다. 특히 쉬운 책만 찾다가는 잘못된 길로 갈 수 있다.)

6.3. 입문용 C언어 개발 환경은 gcc나 clang이 좋다. 단 GUI IDE환경부터 쓰는 것은 피하는 것이 좋다.

6.4. 운영체제는 Linux, UNIX, MacOSX, Windows든 상관없다. 그러나 리눅스를 추천한다.(보통 VMware나 Virtualbox 가상 머신에 설치하는 것도 좋다)

6.5. 공짜는 없다. 최소한 책은 사서 보자. (책장에 꼽아두고 계속 읽어서 완전히 소화해야 한다.)

6.6. 대충 인터넷 검색으로 배울려고 하지 말자. 나중에 정통으로 배운 사람에게 걸리면 민폐 프로그래머 된다.

6.7. 빠르게 단기 속성으로 배우는게 중요한게 아니다. 올바르게 배우는 것을 목표로 삼아야만 한다.

6.8. 의심해라. 책이든 인터넷 블로그의 글이든 의심하자. 의심해서 나쁠 것은 없다. 오히려 의심을 쉽게 거두는 것을 두려워 하는 것이 좋다. 의심은 진리에 접근하는 좋은 방법이다.



(추신) 공짜로 떠먹여준다는 태도를 버려라.

값어치가 있는 것은 유형이든 무형이든 손쉽게 얻을 수 없다.

쉽거나 공짜로 얻을 수 있는데 값어치가 높다?? 그런건 없다.

공짜, 쉬운것만 찾으면 절대로 발전하지 못한다.

특히 어려운 내용이 나오면 바로 포기하고, 쉬운 책이나 쉬운 설명만을 쫓아다니면 절대로 발전할 수 없다. 

어려운 문제로 고민하는 시간은 공부에 있어 필수다.


질문하는 방법을 제대로 익혀라.[2]

무엇을 하려고 했고, 어떤 문제가 발생했고, 자신이 모르는 것이 정확히 무엇인지 질문할 수 있어야 한다.

밑도끝도 없이 질문하거나 문제를 풀어달라고 하면 RTFM 이상의 좋은 소리를 듣지 못할 것이다.


또한 회사나 학교의 고수 선배에게 원포인트 레슨을 받았으면 하다못해 커피나 간식이라도 사서 감사를 표해라.

그렇지 않으면 누가 당신에게 자신의 시간을 쪼개서 가르침을 주겠는가?

고수일수록 바쁘고 급여가 쎄기 마련이다.

그런 사람이 당신을 위해 소모한 시간을 돈으로 환산해봐라.

(예를 들어 시급 25만원짜리 인력이 당신을 1시간 가르쳤다고 생각해보라)


그래서 회사에서는 신입을 뽑을 때 태도를 중시한다. 그게 바로 발전 가능성을 좌우하기 때문이다.

비인부전(非人不傳)이라는 말이 있듯이 배우고자 하는 사람이라면 태도가 중요한 법이다.



[1] Open Standards. http://www.open-std.org/

[2] 김정균. 초보자들이 처음 시작을 하는데 필요한 상식. https://wiki.kldp.org/wiki.php/DocbookSgml/Beginner_QA-KLDP


* 본글의 댓글 중에 사적인 질문이나 본문글과 무관한 내용은 정기적으로 삭제하고 있습니다. 댓글이 너무 많아서 본글을 읽기 힘들어지기 때문에 어쩔 수 없이 내린 방법이니 양해해주시기 바랍니다.

* C++에 대한 책 추천을 하는 댓글이 많아지는데, C++도 C와 마찬가지로 Modern C++의 표준인 C++11, C++14을 다루는 책으로 공부하시면 됩니다. 대부분 원서이며 국내서 중에는 C++11, C++14를 다룬 책은 없는 것으로 압니다. (번역서는 몇 권 있습니다.) C++ 책 목록은 나중에 1만년 뒤쯤에 따로 정리하겠습니다. ^^

243 Comments
  • 이전 댓글 더보기
  • 프로필사진 훈코 2019.12.24 03:24 안녕하세요 선생님 IT분야에 관심이 많아 C언어공부관련 조언을 찾던중 큰 도움을 받았습니다. 너무 감사합니다.
    주위에 아는 어른도없고, 다른 고수분의 블로그에도 해당내용이 없어 궁금한점을 묻고자 댓글남깁니다
    위에 앞서 중급 레벨을 "대체로 운영체제나 시스템 프로그래밍에 대해 이해하고 효율적인 프로그램을 구성할 수 있는 레벨을 의미합니다." 라고 하셨는데, 그렇다면 고수 레벨은 어떻게 정의하시는지요?? 그리고 중급에서 구로헌 고수레벨에 달성하는데 책이나 방법을 추천해주실수있으신지요?
  • 프로필사진 sunyzero 2019.12.24 19:40 신고 중급 이상의 길은 세부 전공이나 분야가 갈리기 때문에 특별히 고수 혹은 고급이라고 부르는 기준은 없습니다.

    즉 중급 이상이 되면 이미 같은 필드에서 활약하고 있는 고수급의 peer들이 실력을 인정하는 것이므로 상대적이라는 뜻 입니다.

    어차피 중급 이상으로 성장하다보면 고수들을 알게됩니다. 우물안 개구리가 되지 않으려면 고수들의 코드를 보는 것도 매우 중요합니다. 그래서 고수들의 코드를 보다보면 자연스럽게 자신의 실력을 가늠해볼 수 있게 됩니다.

    중요한 것은 문법 떼는 것은 중급도 아니고 초급 레벨 이하라는 것을 유념해두고, 항상 겸손해야 합니다.
  • 프로필사진 꾸준히 2019.12.27 11:06 안녕하세요! 제가 현재 이글을 보면서 c premium plus를 공부해나가고 있고 로봇과 관련된 대학원에 입학해 있습니다. 현재 제가 부족한게 너무나도 많다고 생각들지만 차근하다보면 언젠가 달성하지 않을까라는 생각으로 임하고 있습니다.
    본론부터 말하자면 제가 현재 작은 시스템(라즈베리파이, 아누이노 우노, 자비어, 젝슨나노 등) 다양한 시스템들을 이용하면서 메모리관리에 필수적으로 활용되는 c언어와 c++을 공부하려고 합니다.
    하지만 메모리 관리 부분에 대학 개념과 메모리 물리와 가상에 대한 명확한 구분이 없어서 어렵다고 생각합니다. 메모리 자체관리를 위해 어떠한 수업 또는 책? 강좌를 들어야하는지 좀 알려주실수 있겠습니까?? 앞으로 꼬옥 저에게 필요할 부분이라 생각들어 이렇게 부탁드리겠습니다.
    읽어주셔서 감사합니다
  • 프로필사진 sunyzero 2019.12.27 21:41 신고 일반적으로 다음과 같은 3과목들에서 배웁니다. 운영체제론(OS, Operating Systems), 컴퓨터구조(CA, Computer Architecture), 컴퓨터 시스템(CS, Computer System)과목인데, 학교마다 3과목이 다 있지 않는 경우도 있습니다.

    윗글에도 적었듯이 CS 과목은 주로 CSAPP책으로 수업을 나가는 경우가 많습니다.

    그리고 물리메모리와 가상 메모리에 대해서는 paging, segmentation을 다루는 부분에서 주로 다룹니다.
    그러나 원론적인 것 외에 리눅스를 사용하는 경우에는 리눅스의 anonymous, filebacked 그리고 mmap등의 구현과 사용에 대해서 따로 공부하셔야 합니다. file과 memory는 서로 사본과 원본의 관계가 있기 때문에 이에 대한 이해가 필수입니다. 참고할 글로는 https://sunyzero.tistory.com/260 에 적어두었으니 읽어보시기 바랍니다.
  • 프로필사진 droplet 2020.01.15 22:19 이글 보고 정말 많이 배워갑니다
    현재 중학생인데 C primer plus 책사서 독학중입니다.
    주변에 아는사람이 없어 물어볼사람이 없습니다 ㅠ
    막연히 프로그래밍에 관심이 있어 c를 공부중인데 그저 이렇게 프로그래밍연습정도만 해도 나중에 도움이 될까요?
  • 프로필사진 sunyzero 2020.01.16 23:02 신고 무슨 대회 준비가 아니고서는 추천하지 않습니다. C언어는 대학에서 공부해도 충분합니다.

    오히려 첫 프로그래밍 언어로 파이썬이나 자바스크립트를 배우는게 좋을 수도 있습니다.
  • 프로필사진 전자공학도 2020.01.23 01:39 운영체제를 리눅스를 추천하는 이유가 뭔지 여쭤봐도 될까요?
  • 프로필사진 sunyzero 2020.01.23 08:25 신고 C언어의 태생 목적이 UNIX를 재작성하기 위해서 만들어진 언어입니다.
    그리고 C언어로 인해서 만들어진 UNIX가 이식성을 가지기 위해 제정된 것인 표준이라고 불리는 것들입니다.

    이런 연유로 C언어 표준(ISO/IEC 9899)과 POSIX 표준(IEEE std 1003.1, 약칭 POSIX.1)은 서로 밀접한 관계를 가지고 있습니다.

    따라서 표준과 이식성에 대해서 공부하기 위해서는 POSIX 시스템에 대해 알아야하고, 이는 곧 C표준도 같이 다뤄야 함을 의미합니다. 그리고 현재 POSIX 시스템을 가장 잘 구현한 OS가 리눅스입니다.
  • 프로필사진 꾸준히 하자 2020.02.20 18:03 블로그 내용 잘 읽었습니다.
    1. 컴퓨터 구조는 어떤 책을 추천하시나요?(원서, 번역판 둘 다 추천해주시면 감사한데 작성자님께서 주로 원서로 공부를 하셨다면 원서를 추천해주셔도 됩니다!!)
    2. 공룡책 번역판도 혹시 읽어보셨다면 공룡책 번역판의 번역 질은 어떤지도 궁금합니다.
  • 프로필사진 sunyzero 2020.02.23 18:10 신고 David Patterson교수의 책을 주로 봅니다.
    개정이 여러번 되어서 최근 번역본의 질은 잘 모르겠습니다.
  • 프로필사진 아직은초보 2020.04.24 20:56 3년전 군대에서 이 글을 읽고 꽤나 충격을 받았습니다. 제가 12년도 고등학생 때 C로 처음 프로그래밍에 입문하고 대학교에서도 C를 사용하는 수업을 2개나 들었는데 C언어 표준이란게 존재한다는 것을 말해준 사람이 없었거든요. 이 글을 읽으면서 그럼 '난 C를 헛공부 한건가? 자료구조도 이것저것 다 짤 수 있는데?' 같은 생각도 들어서 기분이 굉장히 찝찝했더랬죠. 또, C의 기본 개념이라 말하신 14개 질문 중 2개 밖에 답을 못했기도 했고...

    결국 그 찝찝함에 못이겨 KNK 책을 구매하고 영어사전 껴가며 겨우겨우 읽었습니다. 6,70% 정도 읽었을 때 다시 이 글을 찾아오니 질문 중 5~7개 정도 답할 수 있었습니다. 영어가 약해 여러번 반복해서 읽느라 시간은 오래 걸렸지만 그만한 가치는 있었던 것 같습니다.

    이후 한동안 별도로 C 공부를 안하다가 최근 괜찮은 인터넷 수업(유료강의)을 수강하고 오니 13개나 답할 수 있게 되었군요. (API는 알았지만 ABI는 몰랐답니다 ㅠㅠ)

    아무튼 이 글을 부정적으로 받아들였던 예전과 다르게 지금은 이 글의 내용 하나하나가 다 옳은 말만 하셨다는게 느껴집니다. 표준에 관한 내용이나 개발환경에 대한 내용도 그렇고, 특히 공감갔던 부분은 학습법에 대한 내용이네요. 독학 보다는 최대한 좋은 선생이나 멘토를 찾는게 효율이 배로 차이나는건 직접 겪어보니 알겠더군요.
    아직도 많이 부족하다 생각하지만 그래도 이 글을 읽었던 덕분에 여기까지 올 수 있었던 것 같습니다. 좋은 글 정말 감사드려요.
  • 프로필사진 sunyzero 2020.04.27 13:25 신고 좋은 결실을 맺을 수 있게 되어 기쁩니다. 앞으로 좋은 일만 가득하시기 바랍니다.

    그리고 많은 분들이 정도를 걸을 수 있게 주변에 많이 소개해주세요. ^^
  • 프로필사진 raphaiel 2020.05.30 17:21 현재 c를 배웠다가 표준을 공부해보려고 하고 있습니다. 찾아보니까 c18버전의 표준까지 나왔던데 현재 2020년도 기준으로도 knk c99표준 책으로 공부해도 되는걸까요? 아직 실무에서(해외랑 한국 모두) c99표준을 주로 사용하는지가 궁금합니다. 현재 주로 쓰이는 표준이 c11 또는 c18로 바뀌었다면 그에 따라 다른책으로 공부하는게 맞지 않을까란 생각이 들어 적어봅니다. 혹시 맞다면 그에 따른 책도 추천 부탁드려요. 원서도 상관없습니다. 좋은 정보 많이 알려주셔서 감사해요.
  • 프로필사진 sunyzero 2020.05.31 20:25 신고 2020년 현재도 c99가 제일 많이 쓰이고 있습니다. c11의 경우는 적어도 제가 주로 작업하는 금융이나 IoT 실무에서 사용하는 경우는
    못봤습니다. (건너 들은 얘기로 사용한다는 곳을 한 곳 듣기는 했는데 직접 확인해본 것은 아니라 반신반의합니다. C11을 쓴다고 해놓고 사실상 c99로부터 물려받은 기능만 쓰는 곳도 많아서요.)

    c언어는 c99에서 modern한 특징을 도입하면서 크게 변했기 때문에 c99의 특징을 배우는게 중요한 것이고, c11이후로는 대부분 수정이나 세부기능의 가감이므로 나중에 배우셔도 됩니다.
  • 프로필사진 ㅇㅇ 2020.07.14 13:18 CSAPP를 보고나서 KNKING을 봐도 괜찮을까요? 서문에는 자바나 C++/C에 익숙한사람들을 독자로 예상하고 있다고 나오는데 진도나가는데 C언어에 대한 깊은 이해가 필요한지 알고싶어서 질문을 드려봅니다. 1학년때 C언어과목에서 벼락치기로 B+나왔지만 메모리/할당문제로 많이 애를 먹었던게 기억이 납니다. 학부시절 공부를 이론공부를 소홀히해 지금부터라도 다시 탄탄히 쌓을려고해서 조언을 구해봅니다.
  • 프로필사진 sunyzero 2020.07.14 18:17 신고 한번 시도해보는 것도 괜찮을 것 같습니다. 어렵다는 분들도 있는데, 반대로 쉽고 오히려 이해가 잘됐다는 분들도 있습니다.
  • 프로필사진 ㅇㅇ 2020.07.14 19:36 답변감사합니다. 한번 시도해보고 아니다 싶으면 KNK랑 같이 병행해보겠습니다.
  • 프로필사진 tky7068 2020.08.08 06:53 신고 참고가 되었습니다. 감사합니다. ^^
  • 프로필사진 ㅇㅇ 2020.10.19 20:15 근본잇는글 감사합니다. 22
  • 프로필사진 ㅇㅇ 2020.10.22 15:55 좋은 추천글 감사합니다. 혹시 Modern C (저자 Jens Gustedt)을 보신 적이 있으시다면 어떻게 생각하시는지 여쭤보고 싶습니다.
    에전에 c언어 문법만 땐 초보인데 개념이 불확실하게 잡힌 것 같아 이 책과 본문의 KNK책과 고민하고 있습니다.
  • 프로필사진 sunyzero 2020.10.24 22:14 신고 결론만 먼저 이야기 하면 가능하다면 두 책을 다 보시고, 그 중에서 KNK를 먼저 보는 것을 추천드립니다.

    왜냐하면 두 책은 방향이 좀 다릅니다. KNK는 진짜 입문서이고, Modern C는 이미 C를 이미 배운 사람들에게 Modern C(C99,C11)을 알려주는데 더 적합한 용도의 책입니다.

    다만 Modern C 책은 C11의 ISO C thread를 다루는데, 이 부분은 pthread의 하위 호환이라 실질적으로는 잘 쓰이지 않는 부분입니다.(개인적으로 그냥 한번 읽기만 해도 될듯 합니다) 따라서 UNIX 스레드를 사용하려면 C11보다 POSIX(SUS의 system interface부분)의 시스템 프로그래밍 부분을 보시는게 더 좋습니다. 이는 signal부분도 마찬가지입니다. C표준에서 주로 쓰이는 signal함수는 obsolete function으로 sigaction으로 대체되었습니다. C11이 좀 애매한 부분이 꽤 있어서 C11의 일부 기능은 POSIX 기능으로 대체하는 것이 필요합니다. 이런 부분은 시스템 프로그래밍에서 다룹니다.
  • 프로필사진 ㅇㅇ 2020.10.26 18:12 친절한 답변 감사드립니다. 많은 도움이 되었습니다.
  • 프로필사진 오메 2020.11.12 12:40 이공계 대학생이고 현재 전자공학을 전공중입니다
    컴공 만큼은 아니여도 전자과도 어느정도 코딩 지식이 있어야 해서 군휴학동안 c언어와 java를 배우려고 합니다
    현재 그냥 매우 기초적인 책으로 공부하고 있습니다만
    이 글을 보고 나니 시작부터 잘못된건가 싶습니다
    저는 전문가 수준까지는 필요하진 않는데도 작성자께서 알려주신대로 과정을 밟는게 좋을까요?
  • 프로필사진 sunyzero 2020.11.12 18:06 신고 전자과이시고 졸업후 전공분야로 진출하실거면 꼭 전문가를 목표로 해야 합니다.(요새는 어설픈 수준으로는 일정 레벨에서 도태됩니다. 비전공자와 차별을 두려면 꼭 전문가 레벨을 목표로 잡으셔야 합니다.)

    게다가 전자과라면 컴공보다 더 엄격하게 배워야 합니다. 왜냐하면 요즘 전자과는 대부분 커널 레벨을 건드리는 작업이 많은데, 실제로는 ARM 리눅스 베이스나 STM32같은 것을 많이 다룹니다. 이게 칩마다 특성도 다르고 여러가지 특징이 있는데, 이건 C와 하드웨어 지식이 제대로 잡혀있어야만 제대로 된 프로그래밍이 가능합니다.

    실제로 커널 레벨이나 디바이스 작성시에 C에 대한 개념을 잘못 잡은 사람는 아주 사소한 warning 수준의 미스를 종종 발생시킬 수 있습니다. 이게 매우 사소한 워닝이라 공부할 때는 별거 아니지만, 실무에서는 참혹한 결과를 만듭니다. 시스템이 멈춰 버리거나 잘못된 수치가 나올 수도 있기 때문입니다. 실제로 이런 케이스를 몇 번이나 본 적이 있습니다. 당연히 해당 회사는 손해를 많이 봤지요.

    십수년전에는 정보의 부족으로 인해 잘못된 교재지만 한글이면서 쉽다는 이유로 그럭저럭 대충 배웠지만, 그런 선배세대들은 대부분 회사에서 문제를 일으키고 시행착오를 많이 겪었습니다.(그 과정에서 많은 손해도 있었죠) 그러나 지금은 충분히 좋은 교재도 많고, 제대로 배울 수 있는 기회도 많으니 이왕이면 제대로 배우는게 좋습니다.

    또한 전자과라면 우선적으로 C를 먼저 배우시는게 좋습니다. 자바는 전자과 베이스에서는 그다지 많이 쓰이지 않습니다.(심지어 전자과 쪽에서는 C++조차도 덜 쓰이는 편입니다.)
  • 프로필사진 whyrano 2020.11.14 10:15 컴퓨터 공학과 진학을 희망하는 고등학생입니다.
    파이썬을 겉핥기로 공부했지만 그건 순전히 프로그래밍에 흥미를 붙이기 위해서였습니다. 제대로 c언어를 한번 배워 보고 싶습니다.
    교재는 말씀하신 대로 KNK를 사용하려고 하는데, 혹시 괜찮으시다면 인터넷 강의도 하나 추천해 주실 수 있을까요?
  • 프로필사진 sunyzero 2020.11.16 09:36 신고 저는 특별히 경시대회에 나가는 경우를 제외하고, 단순히 공부 때문에 중고교 시절에 C언어를 접하는 것은 좋지 않다고 생각합니다. 비전공일 때는 파이썬만 접하셔도 충분합니다.

    C는 되도록이면 대학에 진학하고 배우셔도 늦지 않습니다. 문법만 따지면 현존하는 다른 언어(예:파이썬)보다 C언어의 문법은 매우 간단하기 때문에 운영체제나 관련 개념만 잘 다지면 배우는데 오래 걸리지 않습니다.

    C에 대해 과도한 환상을 가지거나 미리 배워야 할 필요는 없습니다.
  • 프로필사진 hyuntaek 2020.11.23 16:28 안녕하세요. 대학교에서 수학과와 컴퓨터 공학과 복수전공중인 학생입니다. 현재는 휴학중에 있으며 1년 정도 알고리즘에 대해 공부를 하고 복학을 하려고 생각중입니다. 프로그래밍 수업은 java만 들은 상태입니다. 알고리즘 공부를 하려고는 하나 사실 C언어 C++에 대해서는 아직 제대로 공부해본 적은 없습니다. 보통 알고리즘에 대해서 공부할 때 C++ 언어를 많이 사용한다고 해서 C++과 병행해서 공부하려고 생각중입니다.
    (현재 C언어와 C++에 대한 문법 지식은 별로 없는 상태입니다...)
    1. 알고리즘 공부를 하면서 C++에 관해 모르는 부분을 그때그때 공부하는 것은 괜찮은지
    2. 괜찮지 않다면 알고리즘 공부를 하기 전에 어떤 언어를 공부하면 좋은지, 그 언어를 다루는 수준은 어느 정도까지 인지
    위 질문에 대해 답변해주시면 감사하겠습니다. 제 생각은 알고리즘 공부를 하면서 C++에 관해 모르는 부분을 공부하면서 채우려 했으나 이 글을 보니 제가 아무것도 모르고 그냥 막연히 잘못 공부하는 건 아닌지 생각이 듭니다.
  • 프로필사진 sunyzero 2020.11.24 01:30 신고 1. 알고리즘 풀이를 하면서 C++문법을 공부하는 방법은 추천하지 않습니다. 왜냐하면 C++을 사용하는 알고리즘 풀이는 속도 경쟁 때문에 비표준이나 문제를 내포한 코드를 남발하는 경우가 많은데, 처음부터 비표준을 남발하는 코드로 배웠다간 실무에서 심각한 코드를 만들 가능성이 높습니다. 비표준 자체가 나쁜 것은 아니지만 어떤 경우에 비표준을 사용해야 하는지 정확한 용처를 배우지 못하면 사회에서는 민폐 프로그래머가 될 가능성이 높아집니다.
    (원래 실무에서 사용가능하면서 안전하고 빠른 코드를 작성하는 것과 속도 경쟁을 위해 대부분의 규칙을 무시하고 빠른 알고리즘 코드를 작성하는 것은 크게 다릅니다.)

    하지만 반대로 먼저 정통으로 문법을 배운 다음에 취업이나 탐구 목적으로 알고리즘 공부를 하는 것은 좋은 길 입니다.

    2. 알고리즘 자체를 배우는데는 굳이 C++은 필요없습니다. 차라리 파이썬을 배우는게 더 낫습니다.

    알고리즘 사이트에서 경쟁을 통해 높은 랭커가 되고자 한다면 C++을 배워야 하겠지만, 그건 공부의 길과는 크게 상관이 없습니다.
  • 프로필사진 ㅇㅇ 2020.12.10 01:39 c언어를 배우기 위해 필요한 지식들은 뭐가있나요?
  • 프로필사진 sunyzero 2020.12.13 11:18 신고 OS와 하드웨어쪽 지식이 일부 필요합니다.
  • 프로필사진 Sky 2020.12.13 05:05 안녕하세요 돌아오는 1학기에 복학하는 컴퓨터공학과 학생입니다.
    먼저 글을 읽으면서 1학년때 visual studio를 사용하여 공부를 한게 조금은 후회가 됩니다...
    (이 과정으로 코딩에 흥미를 붙이긴 하였네요.ㅎㅎ)
    복학전까지 공부할 책을 찾고있었는데 KNK나 독해가 안된다면 C primer plus로 공부해야겟다고 마음먹었습니다.
    여기에 리눅스도 같이 공부해보려고하는데 혹시 리눅스 책도 몇권만 추천해 주실 수 있으신지 조심히 여쭤봅니다.
  • 프로필사진 sunyzero 2020.12.13 11:33 신고 리눅스는 국내서 중에 관리자용 서적으로 정광섭님의 책 내용이 좋지만, 기초책은 아닙니다.

    만일 리눅스를 시작부터 하신다면 국내서는 마땅한 것이 거의 없습니다. 시중에 나와있는 판매순위가 높은, 유명한 리눅스 기초책조차 인터넷 내용을 짜깁기한 흔적을 보이고 있고, 심지어 그 짜깁기한 내용이 틀린 경우가 꽤 있기 때문입니다. 몇몇 판매순위가 높은 리눅스 국내서는 저자가 리눅스뿐만 아니라 운영체제나 네트워크를 제대로 이해하고 있다고 보기 어려울 정도였습니다.(기초개념 뿐만 아니라 명령어 조차 틀린 경우가 많았습니다.)

    따라서 국내저자가 쓴 책보다는 외국번역서인 "리눅스 커맨드라인 완벽 입문서"를 더 추천하는 편입니다. 하지만 이 후 리눅스를 더 잘 사용하시려면 직접 설치해서 최소 반년은 리눅스를 메인 운영체제로 사용하고, 되도록이면 윈도우즈를 사용하지 않는게 제일 중요합니다.
  • 프로필사진 별명없다 2020.12.14 18:44 c언어를 배우기 위해 필요한 OS, 하드웨어 관련 지식을 쌓으려고 합니다. 관련 서적을 추천해주실 수 있을까요..? 감사합니다.
  • 프로필사진 sunyzero 2020.12.29 01:23 신고 CA나 OS, CS에서 쓰이는 바이블 격인 교과서가 있습니다.(서울대나 카이스트 혹은 외국의 IT로 유명한 대학에서 쓰이는 교재목록을 보시면 됩니다.)

    일반적으로 이 과목들은 독학이 어렵습니다. 따라서 독학보다는 강의를 듣기를 추천합니다.
  • 프로필사진 미미 2021.01.05 11:17 안녕하세요. 시스템 쪽을 이론적으로 공부하는 것 좋아하지만, 실제로 짜는 과정에서 감각, 직관이 부족해서 고민하고 있는 컴퓨터공학과 4학년 올라가는 학생입니다. 제가 이번에 인턴을 하면서, c, c++ 로 하드웨어 최적화 일을 맡게 되었는데, 이 과정에서 csapp 를 공부하면서 실습 해보고 물어보고 하면 늘 수 있을까요? 감사합니다.
  • 프로필사진 sunyzero 2021.01.09 22:36 신고 CSAPP에서 다루는 내용은 원론적인 부분이기 때문에 최적화에 기법과는 상관이 없습니다. 통찰력을 기르는데는 도움을 줄 수는 있겠습니다만...

    만일 프로그래밍 레벨에서의 기초적인 최적화를 배우시고 싶다면, profiler를 배우시는게 더 도움이 됩니다. x86의 intel칩 계열이라면 VTune(지금은 이름이 바뀌긴 했습니다만, 그래도 VTune이라고 하면 다 알아듣습니다) 같은 것들도 많이 사용합니다.

    사실 최적화라는 것은 굉장히 광범위하기 때문에 좁게는 컴파일러 옵션, 코드 최적화, profiling그리고 I/O, 네트워크 기능까지 관련되어있기 때문에 콕집어서 최적화는 이런 것이라고 말하기도 애매한 부분이 있습니다. 예를 들어 dirty page를 최소화 하여 writing 기능을 좀 더 빠르게 하기 위해 프로그래밍 언어 레벨에서 더 적은 수의 page cache 메모리를 업데이트 하도록 자료 구조를 작성하는 방법도 있지만, OS의 dirty page의 가용량을 늘려서 해결할 수도 있습니다.
  • 프로필사진 snucse 2021.01.10 01:19 안녕하세요 글 너무 잘 읽었습니다. 소중한 글 남겨주셔서 감사합니다. 저는 이번에 컴공 들어가게 된 새내기입니다..!
    방학 때 저희 학교 컴공과에 근간이 된다고 해서 꼭 C를 공부해서 가려고 했는데 제가 영어 독해가 많이 안돼서 사실 ‘혼자 공부하는 C’ 라는 국어로 된 책을 이미 샀습니다!.... 혹시라도 이 책이 말씀하신 그대로 ‘비표준을 남발하는’ 좋지 않은 책이라면 당장 여기 적어주신 책 중 하나를 사려고 합니다. 혹시 이 책을 보신 적이 있으신가요?
    또 하나 질문은 제가 맥북을 주로 사용해서 맥os 환경에서 이용을 하고자 하는데요! 혹시 말씀해주신 책 세권은 맥os 환경을 고려한 설명을 해주는지 궁금합니다. 제가 이미 산 책은 윈도우 체제를 기준으로 설명을 해주고 있습니다.
  • 프로필사진 sunyzero 2021.01.10 17:51 신고 1. Mac OSX를 쓰셔도 됩니다. 왜냐하면 OSX 자체가 BSD의 분파입니다. 따라서 POSIX 표준을 지원하고 있으므로 Linux나 UNIX와 환경이 거의 같습니다.

    2. 말씀하신 책은 제가 따로 가지고 있지 않아서 잘 모르겠습니다만, KNK의 내용이 어렵지 않으므로 일단 보시고 판단하시는게 좋을 듯 합니다.
  • 프로필사진 ㅁㄴㅇㄹ 2021.01.13 22:09 몇년 전에 본 글인데... 그 때 느꼈던 것(저의 부족함 때문)과는 정반대로, 우연히 다시 읽어 보니 절로 고개가 끄덕거려지네요. 정말 좋은 글입니다.ㅎㅎ
  • 프로필사진 sunyzero 2021.01.14 18:00 신고 감사합니다. ^^
댓글쓰기 폼