Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

C Programming: A Modern Approach second edition a.k.a KNK (2008) Chap.1 본문

C

C Programming: A Modern Approach second edition a.k.a KNK (2008) Chap.1

Daryl 2022. 12. 2. 00:27

C언어를 공부하는 이유는 간단하다. 좋은 프로그래머가 되고 싶기 때문이다.

'씹어먹는 C언어' https://modoocode.com 에서 와닿는 문장이 있어서 가져왔다.

 

"만약 적당히 잘하는 프로그래머가 목표라면,

굳이 컴퓨터 내부가 어떻게 돌아가는지 몰라도 괜찮습니다.
하지만 좋은 프로그래머가 되려면,

컴퓨터의 내부 원리를 아는 것이 필수적입니다.
만약에 C 언어를 배우게 된다면, 컴퓨터 내부 원리를 더 쉽게 이해할 수 있습니다."


즉, 좋은 프로그래머가 되기 위해 컴퓨터 내부 원리를 배우는 거고,

그걸 더 쉽게 이해하기 위해 C언어를 배우는 것이다.
따라서, 좋은 프로그래머가 되려면 C언어를 배워야 하는구나.

난 좋은 프로그래머가 되고 싶었기 때문에 마음에 쏙 드는 이유였다.

 

그래서 C언어 입문 도서 및 공부법을 찾아봤고, 많은 사람들이 KNK 원서를 추천했다.

C의 기초 바이블이고, 프로그래머는 어차피 영어를 잘해야 하니 원서로 보는게 낫다고.

그래서 3개월 정도의 시간을 잡고 공부를 시작했고, 해석이 어려운 부분은 주민하님의 https://wikidocs.net/book/2494 를 참고했다.

 

책에서 공부한 내용과 내가 따로 찾아본 내용을 합쳐 글을 썼다. (위키백과 참고 다수)

큰 글씨가 책 내용, 작은 글씨가 부가적 내용이니 도움이 되길 바란다.

 

 


Chap 1. INTRODUCING C

 

1.1 History of C

Origins

C는 UNIX 운영체제 개발의 부산물이다.

벨 연구소의 켄 톰슨Ken Thompson, 데니스 리치Dennis Ritchie 등이 개발했다.

켄 톰슨이 데니스 리치의 감수를 받는 형태로 설계하였다고 한다.

당시 톰슨은 1969년 DEC PDP-7 컴퓨터로 UNIX 초기 운영체제를 거의 혼자 개발했다.

UNIX는 어셈블리어로 제작되었는데, 그럼 디버깅이나 성능 업그레이드가 매우 힘들다.

그래서 톰슨은 UNIX 개발을 위해 고민하다 좀 더 고급 언어인 B 언어를 만들었다.

 

B 언어는 1966년에 만들어진 BCPL이라는 시스템 프로그래밍 언어를 기반으로 제작됐다. 

BCPL은 1963년에 개발된 CPL(Combined Programming Language) 언어의 Basic 버전.

둘다 케임브리지 대학교에서 개발했고, 멀티 패러다임 프로그래밍 언어이다.

쉽게 말해 여러 종류의 패러다임(ex.함수형, 선언형, 객체지향, etc.)을 지원하는 언어라는 것.

 

톰슨은 Multix(Multiplexed Information and Computing Service)에서 BCPL을 차용했다.

Multix는 1964년 시작된 시분할* 운영 체제 프로젝트이다.

*시분할Time Sharing: 다수가 동시에 운영 체제에 접근 가능하나 서로의 존재를 알 수 없는 환경.

당시 벨 랩에서 멀틱스 개발을 일부 맡았고 톰슨도 그 프로젝트에 종사했었다.

톰슨이 보기에 BCPL은 미니컴퓨터의 메모리 용량에는 너무 무거운 언어였다.

그래서 불필요한 구성 요소(ex.코드 글자수)들을 대폭 정리해서 만든 것이 B 언어.

 

또한 BCPL은 Algol 60(Algorithmic Language)이라는 언어에서 영향을 받았다고 한다.

알골 60은 1960년에 개발되었고, 그를 비롯한 ALGOL 계열 언어들이 또 존재한다(ex. Algol 58).

ALGOL 계열 언어들은 미국의 Fortran(Formula Translation)에 대항하여 유럽이 만든 것이다.

포트란은 1954년에 미국 IBM에서 전문적 과학 계산을 위해 만들었다.

1940년대의 ANIAC, UINBAC 이후 최초의 현대 프로그래밍 언어이며 지금도 종종 쓰인다.

 

이렇게 만들어진 B언어를 이용하여 리치는 UNIX 프로젝트에서 프로그래밍을 했다.

1970년에 벨 랩은 PDP-11 컴퓨터를 지원해줬고, 여기서도 B가 작동 가능해졌다.

이때 톰슨은 UNIX 일부를 어셈블리어가 아닌 B 언어로 프로그래밍 했다.

 

그러다 1971년에 B 언어가 PDP-11의 문자 자료형을 처리하지 못한다는 문제가 발견됐다.

그래서 리치가 컴파일러에 기계어 코드 생성 기능, 자료형 변수를 추가해 New B(NB)를 제작했다.

 

1972년에 전처리기 등이 추가되고 B와는 많이 달라져서 리치가 C 언어라고 명명했다.

1973년에는 UNIX 전체를 C로 프로그래밍할 수 있을 만큼 안정화됐다.  

(그렇지만 어셈블리어가 아닌 언어로 구현된 최초 사례는 아니다.)

이 전환은 확장성*이라는 큰 장점을 가져왔다.

확장성Portability*: 사용자가 원하는 새로운 기능을 추가할 수 있는 특성

 

따라서, C 선구 계보를 간략히 정리해보자면

Fortran (1954)↔ALGOL 58 (1958)→ALGOL 60 (1960)→CPL (1963)→BCPL (1967)→B (1969)→C (1972)→...

정도가 되겠다.

Standardization

C는 70년대 내내 발전했고, 특히 77~79년 사이가 급격했다. 이때 '하얀 책'이 출판됐다.

브라이언 커니핸Brian Kernighan과 리치의 'The C Programming Language' (1978).

K&R은 순식간에 바이블이 되었지만, 일부 기능 설명이 구체적이지 않아 문제가 됐다.

결국 83년부터 미국 규격 협회 ANSI를 중심으로 하여 88년에 C의 표준이 완성됐다.

89년에 ANSI에서, 90년에 국제표준화기구ISO에서 승인 받아 C89(C90)로 불렸다.

95년에 조금 수정되고, 99년에 대대적으로 변화해 ISO 승인을 받아 C99가 되었다.

(지금은 2011년에 ISO 승인을 받아 C11이 나왔고, 2018년에 ISO 승인을 받아 C17까지 나왔다.)

C-Based Languages

아주 많은 언어에 막대한 영향을 주었다. 대표적인 언어를 소개하자면 아래와 같다.

1) C++: C의 모든 특징+ 클래스+ 다른 여러 특징→ 객체 지향 프로그래밍 가능

2) Java: C++ 기반→ C의 여러 특징 공유

3) C#: Java와 C++에 영향 받음

4) Perl: 개발 이후 C의 특징 다수를 공유

 

이러한 새로운 언어들의 인기는 높지만, C언어를 배우는 것은 여전히 중요하다.

첫번째로, C를 공부할 경우 위와 같은 C 기반 언어들을 공부할 때 엄청난 통찰력이 생긴다.

두번째로, C언어로 작성된 프로그램이 여전히 많기에 당장의 유지 보수가 필요할 수 있다.

세번째로, 메모리나 연산 능력이 한정된 새로운 소프트웨어 개발에 아직 C가 사용된다.

 

이 책은 데이터 추상화data abstraction, 정보 은폐information hiding 등을 강조한다.

이것은 객체 지향 프로그래밍에 중요한 역할을 하는 분야들이다.

C++은 이러한 C의 특징을 모두 갖고 있으므로, 이 책을 통해 사실상 C++도 공부하는 것이다.

 

1.2 Strengths and Weaknesses of C

C언어의 본 용도와 철학을 이해하면 장단점 파악에 도움이 된다.

 

용도: 운영체제 또는 시스템 소프트웨어 제작

철학: 시스템 제어 또는 빠른 속도 

 

이를 바탕으로 생겨난 C의 세 가지 특징이 있다.

 

1. C는 저급low-level 언어이다:

시스템을 제어하는 언어들은 byte 단위, 메모리 주소 값 등 기계 수준 개념까지 다룬다.

또한 컴퓨터 자체에 내장된 지시들과 거의 일치하는 연산을 제공해 매우 빨라질 수 있다.

어플리케이션 프로그램의 여러 서비스가 연산에 의존하기 때문에 OS는 느리면 안 된다. 

2. C는 작은small 언어이다:

C는 비교적 한정된 특징만을 제공해 표준 함수*로 이루어진 library에 크게 의존한다.

*함수function: 타 언어에서 procedure, method 등으로 부르는 기능과 비슷하다.

3. C는 관대한permissive 언어이다:

C는 타 언어에 비해 좀 더 많은 자유를 제공한다.

프로그래머가 스스로 뭘 하고 있는지 알고 있다고 가정하기 때문이다.

뒤집어 말하면 에러가 생겨도 구체적으로 알려주지 않는다는 뜻이다.

대다수의 타 언어는 구체적인 에러에 대한 설명을 제공한다.

Strengths

1. 효율성Efficiency

애초에 C는 어셈블리어를 대체하기 위해 만들어졌다. 한정된 메모리 내에서 최대로 빠르다.

2. 확장성Portability

사용하다 보니 발견된 장점이다. 가정집 컴에서도 슈퍼 컴에서도 C로 짠 프로그램은 실행된다.

3. 강력함Power

어려운 작업을 단 몇 개의 줄만으로도 수행할 수 있다. 다양한 자료형과 연산자 덕분이다.

4. 유연성Flexibility

시스템 프로그램 외에도 온갖 애플리케이션 제작에 쓸 수 있다.

또한 타 언어에서 불허하는 기능을 허용하기도 한다. 그래서 버그도 가끔 생긴다.

5. 표준 라이브러리Standard library

C의 최고 강점 중 하나다. 문자열 처리, 메모리 할당 등 유용한 함수가 아주 많은 저장고.

6. UNIX와의 통합Integration with UNIX

C는 특히 UNIX의 변종인 Linux와 만나면 죽이 잘 맞는다.

UNIX의 몇몇 기능은 사용자가 C를 쓸 줄 안다는 전제 하에 제공되기도 한다.

 

Weaknesses

1. 에러 나기 쉬움 C can be error-prone

유연성의 이면. 타 언어에선 쉽게 잡힐 실수가 C 컴파일러에선 잡히지 않을 수 있다.

2. 이해하기 어려움 C can be difficult to understand

타 언어에 없는 기능들이 많고, 그게 잘못 이해되는 경우가 많다. 즉, 가독성이 낮다.

너무 간결해서 오히려 어려울 수도 있고, 유연성이 되려 단점이 될 수 있다.

천재들이 자기들 쓰려고 만든거라서 남들이 보면 못 알아 들을 확률이 높다.

3. 수정이 어려움 C can be difficult to modify

앞으로 유지 보수를 할 생각이 없이 제작된 대규모 프로그램은 수정이 매우 어려울 수 있다.

C는 클래스, 패키지 등 큰 프로그램을 여러 단위로 나누는 기능이 없기 때문이다.

 

Effective Use of C

아래는 C를 효과적으로 사용하기 위한 방법이다.

 

1. 실수 줄이는 방법 익히기 Learn how to avoid C pitfalls

책의 여러 군데에 적혀 있다. [!!!]이란 표시를 해둘테니 잘 캐치하라.

Andrew Koenig의 C Traps and pitfallls 책 추천.

2. 소프트웨어 도구 쓰기 Use software toolls to make programs more reliable

C 컴파일러만 사용하는 건 비추.

lint나 디버거, 또는 비슷한 프로그램 추천.

3. 코드 라이브러리 써서 코드 안정화 Take advantage of existing code libraries

자주 사용되는 라이브러리는 다수가 통상적으로 이용하기에 믿을 만 하다.

이것들은 주로 공용 저작물/오픈소스/상용이다.

예를 들어 UI 개발, 그래픽, 커뮤니케이션, DB 관리와 네트워크 등등...

4. 실용적 코딩 버릇 들이기 Adopt a sensible set of coding conventions

버릇을 잘 들이면 프로그램 가독성도 좋아지고 유지 보수도 쉬워진다.

일단 책에서는 한 가지 스타일을 가르칠 것이니 잘 따라오라.

5. 허세는 넣어두고 코드는 간결하게 Avoid "tricks" and overly complex code

어떤 때에는 가장 짧은 코드가 오히려 가장 이해하기 어려운 코드이다.

짧다고 다 좋은게 아니니 허세 부리지 말라. 책에서는 가독성 있되 간결한 방식을 권한다.

6. 표준을 지키기 Stick to the standard

대부분의 C 컴파일러는 C99 이상의 C 언어 기능이나 라이브러리를 지원할 것이다.

하지만 확장성을 위해서는 정말 필요한 기능이 아니면 지양하는게 좋다.

 

Q & A

Q: What is this Q&A section anyway? Q&A 섹션에선 뭘 하나?

A: 질문 감사하다. Glad you asked. 대부분 학생들이 가장 자주 하는 질문을 논한다.

또는 해당 단원보다 좀 더 나아간 부분을 다룬다. 자세한 설명을 볼 수 있을 것이다.

 

Q: Is there some way to force a compiler to do a more through job of error checking,

without having to use lint? lint 없이 컴파일러가 좀 더 철저하게 일하도록 강제할 순 없나?
A: 가능하다. GCC 컴파일러에서 에러를 확인하는 옵션은 chap2의 Q&A에서 확인하라.

 

Q: Are there any other tools available besides lint and debuggers? 쟤네 말고 또 추가할 도구는?
A: "바운즈 체커bounds-checker"는 배열 첨자array subscript 확인을 도와준다.

"릭 파인더leak-finder"는 메모리 누수*를 찾아준다.

메모리 누수memory leaks*: 동적으로는 할당되지만 절대로 할당이 해제되지 않는 메모리 블록


글이 너무 길어지니까 쓰기가 힘들다. 다음부터는 주 독자를 나로 정하고 쓰려고 한다.

지금처럼 자세히 적지 않고 대충 내가 알아볼 수 있게만 쓰겠다는 소리다.

내 글을 앞으로 참고하려는 사람이 있다면 복습용으로만 쓰는게 좋을 듯 하다.

 

 

 

'C' 카테고리의 다른 글

KNK Chap.2 (2.8~Q&A)  (0) 2022.12.06
KNK Chap.2 (2.5~2.7)  (0) 2022.12.03
KNK Chap.2 (2.4)  (0) 2022.12.02
KNK Chap.2 (2.1~2.3)  (0) 2022.12.02
C#으로 프로그래밍 입문하기: 헬로 코딩Hello Coding  (1) 2022.12.01
Comments