이 장에서는 전문적인 C프로그래머가 되기 위해서 필요한 기본적인 사항들을 배우기로 하겠다. 

오늘은 다음과 같은 내용을 배울 것이다. 

여러 가지 프로그래밍 언어 중에서 C언어가 훌륭한 이유

프로그램 개발 과정의 4 단계

첫 번째 C프로그램을 작성하고 컴파일해서 실행하는 방법

컴파일러와 링커에서 출력되는 에러 메시지


C 언어의 역사

여러분은 아마도 C언어의 시초가 무엇이고, 어떻게 해서 'C'라는 이름을 가지게 되었 는지에 대해서 많은 의문을 가지고 있을 것이다. C는 1972년 벨 연구소에서 데니스 리치(Dennis Ritchie)에 의해서 개발되었다. 이 언어는 우연히 개발된 것이 아니라 많은 컴퓨터에서 사용되는 UNIX 운영 체계를 제작하는데 사용한다는 특별한 목적을 가지고 개발되었다. 즉, C 언어는 처음부터 프로그래머들이 작업을 완료하는데 유용하게 사용할 수 있도록 고안되었다. 이처럼 C 언어는 뛰어난 기능과 융통성을 제공해 주었으므로 오래지 않아 벨 연구소 뿐만 아니라 다른 여러 곳으로 빠르게 보급되었다. 많은 프로그래머들은 모든 프로그램을 작성하기 위해서 C 언어를 사용하기 시작했다. 그러나 서로 다른 곳에서 C 언어를 사용하는 프로그래머들은 C 언어를 약간씩 수정하여 각자 자신만의 독특한 환경을 구성 하기 시작했고, 결과적으로 C 언어로 작성된 프로그램들 간에는 미묘한 차이가 생기게 되었으며, 그로 인해 많은 프로그래머들은 다른 곳에서 작성된 프로그램을 정상적으로 실행하기 위해 다시 수정해야 하는 상황이 발생했다. 이러한 문제점을 해결하기 위해서 미국의 국가 표준 협회(ANSI : American National Standard Institute)에서는 C에 대한 표준을 만들기 위해서 1983년 위원회를 결성했고, ANSI 표준 C(ANSI Standard C)라고 알려진 표준안을 발표했다. 이제, C 언어의 명칭에 대해서 알아보도록 하자. C 언어는 이전에 사용되던 B언어를 계승한다는 점에서 'C'라는 이름을 가지게 되었다. B 언어도 벨 연구소의 켄 톰슨 (Ken Thompson)에 의해서 개발된 것이다. B 언어의 명칭이 어떻게 정해졌는지는 (B = Bell Labs) 쉽게 추축할 수 있을 것이다

오늘날 컴퓨터 프로그램을 작성할 때에는 C, 파스칼(Pascal), 베이직(BASIC), 자바(Java) 와 같이 많은 고급 언어 중에서 필요한 것을 선택하여 사용할 수 있다. 이런 대부분의 프로그래밍 언어는 특정 작업을 처리하는 데 있어서 최상의 환경을 제공해 준다. 그러나 많은 컴퓨터 전문가들은 다음과 같은 몇 가지 이유를 예로 들어서 여러 가지 프로그래밍 언어 중에서도 C 언어가 가장 뛰어나다고 주장한다


- C 언어는 강력한 기능을 제공하며 융통성을 발휘하는 언어이다. C 언어를 사용하여 수행할 수 있는 작업의 종류에는 아무런 제한이 없다. 프로그래밍 언어 자체에는 전혀 제한 사항이 없다. C 언어는 운영체제(operating system), 문서 작성기(word processor),  스프레드시트(spreadsheet)와 같은 응용 프로그램을 제작하는 데 사용될 수 있으며, 심지어는 다른 언어의 컴파일러를 개발하기 위해서도 사용될 수 있다

- C 언어는 전문적인 프로그래머들이 가장 선호하는 프로그래밍 언어이다. 그래서 시중  에는 매우 다양한 C 컴파일러와 유용한 유틸리티 프로그램이 존재한다


- C 언어는 이식성이 뛰어나다. 이식성(portable)이 뛰어나다는 것은, 예를 들어 IBM PC  와 같은 컴퓨터 시스템에서 작성된 C 프로그램이 DEC VAX 시스템과 같은 시스템에서 도 거의 수정 없이 컴파일되고 실행될 수 있다는 것을 뜻한다. 이식성은 앞에서 설명했던 C 컴파일러에 대한 여러 가지 규칙을 제안하는 C 언어의 ANSI 표준에 의해서 더욱 높아 지게 된다. 


- C 언어는 키워드(keyword)라는 몇 개의 단어만을 사용하여 프로그램을 구성하는 간편 함을 제공한다. 키워드는 C 언어의 기보적인 동작을 수행하는 데 사용되는 단어이며,  예약어라고도 한다. 어떤 사람들은 더 많은 키워드를 가지는 언어가 더욱 강력한 기능을  제공할 것이라고 생각할 것이다. 그러나 실제로는 그렇지 않다. C 언어를 사용하여 많은 프로그래밍 작업을 수행함에 따라, 기본적인 키워드만으로도 대부분의 작업을 수행하는 프로그램을 작성할 수 있다는 것을 알게 될 것이다


- C 언어는 모듈을 기본으로 한다. C 언어로 작성되는 프로그램은 함수(function)라는 각각의 루틴별로 작성될 수 있으며, 효율성 면에서도 하뭇 단위로 작성되는 것이 좋다. 각각의 함수는 다른 응용 프로그램을 작성할 때에도 사용될 수 있다. 프로그래머는 필요에 따라 함수에 자료를 전달하여 유용하고 재사용 가능한 프로그램을 작성할 수 있다. 이런 몇 가지 특징으로도 알 수 있듯이, C 언어는 가장 뛰어난 프로그래밍 언어라고 할 수있다. 참고로 C++라는 새로운 언어에 대해서 알아보도록 하자. 여러분은 이미 C++와 객체 지향 프로그래밍(OCP : Object-Oriented Programming) 방식에 대해서 들은 적이 있을 것이다. 또한, C와 C++ 언어의 차이점은 무엇이고, C 언어를 배운 다음에 다시 C++ 언어를 배워야 하지 않느냐는 의문을 가질 수도 있을 것이다. 그러나 이 점에 대해서는 전혀 걱정할 필요가 없다. C++ 언어는 C 언어의 기본적인 기능을 그대로 가지고 있으며, 추가로 객체 지향 프로그래밍에 필요한 사항을 포함하고 있는 언어이다. 그래서 나중에 C++ 언어를 배우더라도 C 언어에 대해서 배우는 거의 대부분의 내용이 C++ 언어에서도 적용되므로 많은 어려움이 없을 것이다. 결과적으로, C 언어를 배우는 것은 현재의 가장 강력하고 유용한 프로그래밍 언어를 배우는 것일 뿐 아니라, 미래에 대한 준비 로 객체 지향 프로그래밍의 기초를 배우는 것이기도 하다. 최근에 많은 관심을 모으고 있는 또다른 언어로 자바(Java)가 있다. 자바는 C++와 마찬가지 로 C를 기반으로 하는 언어이다. 만약 나중에 자바를 배우게 된다면 대부분의 내용이 C 언어에도 적용되는 것임을 알 수 있을 것이다.


일반적으로 어떤 문제를 해결하기 위해서는 단계별로 하나씩 해결해 나가야 한다. 우선, 문제점을 분명히 파악해야 한다. 문제점이 무엇인지 정확히 모른다면 해결 방법을 찾을 수 없다. 일단 문제점을 파악하고 나면 문제를 해결하기 위한 계획을 세울 수 있다. 또한, 계획을 작성한 후에는 실제로 필요한 작업을 수행할 수 있다. 마지막으로, 계획에 따라 필요한 작업을 수행하고 나면 문제가 바르게 해결되었는지 확인해볼 필요가 있을 것이다. 이런 개념은 프로그래밍에 있어서도 동일하게 적용되며 다른 많은 경우에도 적용될 것이다. C 언어를 사용하여 프로그램을 개발하고나 또는 동일한 문제를 해결하기 위해 다른 어떤 프로그래밍 언어를 사용하여 프로그램을 개발할 때에는 다음과 같은 일련의 과정을 따라야 한다. 


프로그램의 목적을 결정한다.

프로그램을 작성할 때 사용하기 원하는 방법을 결정한다. 문제를 해결하기 위해서 프로그램을 작성한다.

결과를 확인하기 위해서 프로그램을 실행한다. 

첫 번째 단계인 프로그램의 목적으로는 문서 작성기나 데이터베이스 프로그램을 작성하는 것을 예로 들 수 있다. 또는 화면 상에 사용자의 이름을 출력하는 것과 같은 간단한 목적도 될 수 있다. 만약 어떤 목적을 설정하지 않았다면 프로그램을 작성하는 것이 필요하지 않을 것이고, 전체적인 과정은 첫번째 단계에서 종료될 것이다. 두 번째 단계는 프로그램을 작성할 때 사용하기 원하는 방법을 결정하는 것이다. 이에 대한 예로는 주어진 문제를 해결하기 위해서 컴퓨터 프로그램을 작성할 필요가 있는가, 어떤 자료를 조사해야 하는가, 또는 어떤 공식을 사용하여 문제를 해결할 것인가를 결정하는 것이다. 두 번째 단계에서 프로그래머는 알아둘 필요가 있는 사항과 문제를 해결하기 윟나 순서를 결정해야 한다. 예를 들어, 원의 면적을 구하기 윟나 프로그램을 작성해야 한다고 가정하자. 첫 번째 단계는 윈의 면적을 구해야 한다는 분명한 목적이 있으므로 완료된 것이다. 두 번째 단계에서 원의 면적을 구하기 위해서 필요한 것을 결정해야 한다. 예제에서 원의 반지름을 알고 있다고 하자. 프로그래머는 원의 면적을 구하기 위해서 pr2이라는 공식을 사용할 수 있을 것이다. 이제 두 번째 단계까지의 작업이 완료되었으므로 실제 프로그램 개발 과정인 세 번째와 네 번째 단계로 진행할 수 있을 것이다


프로그램 개발 과정은 다시 단계별로 나눌 수 있다. 우선, 첫 번째 단계에서는 소스 코드 (Source code)를 작성하여 디스크 파일로 저장하기 위해서 에디터를 사용한다. 두 번째 단계에서는 오브젝트 코드(object code)를 생성하기 위해서 소스 코드를 컴파일 (compile)한다. 세 번째 단계에서는 실행 파일(executable file)을 생성하기 위해서 컴파일된 코드를 링크(link)한다. 마지막으로 네 번째 단계에서는 작성된 프로그램이 정상적으로 동작하는지 확인하기 위해서 프로그램을 실행한다. 


4.1 소스 코드의 입력

소스 코드는 프로그래머가 원하는 작업을 컴퓨터가 수행하도록 지시하는 데 사용되는 일련의 명령문(statements)이나 명령(commands)이다. 앞에서도 설명했듯이, 프로그램 개발 과정의 첫 번째 단계는 에디터를 사용하여 소스 코드를 입력하는 것이다. 예를 들어, 다음과 같은 한 줄의 C 소스 코드가 있다. 


printf("Hello, Kim!"); 


이 것은 컴퓨터가 'Hello, Kim!'이라는 내용을 화면 상에 출력하도록 지시하는 문장이다. 일단, 이 명령문의 상세한 내용에 대해서는 잠시 미루어 두자. 


▶ 에디터의 사용

대부분의 컴파일러는 소스 코드를 입력하는 데 사용할 수 있는 에디터(editor)를 내장하고 있지만, 일부는 에디터를 내장하고 있지 않다. 여러분의 컴파일러가 에디터를 내장하고 있는지 알아보기 위해서 컴파일러와 함께 제공되는 설명서를 참조하기 바란다. 컴파일러에 에디터가 내장되어 있지 않더라도 많은 에디터 프로그램을 사용할 수 있다. 대부분의 컴퓨터 시스템에는 에디터로 사용할 수 있는 프로그램이 포함되어 있다. UNIX를 사용 중이라면 ed, ex, edit, emacs, vi와 같은 에디터를 사용할 수 있을 것이다. 

마이크로 소프트(Ms)의 윈도우를 사용 중이라면 노트패드(Notepad)가 포함되어 있다. DOS 5.0이상의 버전을 사용 중이라면 Edit를 사용할 수 있다. 또한, 5.0 이전의 DOS버전을 사용 중이라면 Edlin을 사용할 수 있다. PC DOS 6.0 이상의 버전을 사용 중이라면 E를 사용 할 수 있다. OS/2를 사용 중이라면 E와 EPM 에디터를 사용할 수 있다. 대부분의 문서 작성기는 작성된 문서를 형식화(format)하기 위해서 특수한 코드를 사용하고 있다. 이런 코드는 다른 프로그램에서 정상적으로 사용될 수 없다. 그래서 C 언어를 포함하여 거의 모든 프로그램에서는 텍스트의 표준 형식으로 ASCII(American Standard Code for Information Interchange)를 사용한다. 워드퍼펙트(WordPerfect), 아미프로(AmiPro), 워드(Word), 워드패드, 워드스타(WordStar)와 같은 여러 가지 문서 작성기에서는 소스 파일을 독특한 문서 파일 형식뿐 아니라 ASCII 형식의 텍스트 파일로 저장할 수 있을 것이다. 

문서 작성기를 사용하여 작성된 파일을 ASCII 파일 형식으로 저장하기 위해서는 문서 작성기 내에서 ASCII나 텍스트 파일 저장 기능을 선택하면 된다. 소스 코드를 입력하여 파일로 저장할 때에는 적절한 이름을 지정해야 한다. 파일의 이름은 프로그램의 동작을 설명하는 것이어야 한다. 또한, C 프로그램의 소스 파일을 저장할 때에는 확장자로 .C를 사용해야 한다. 소스 파일에 어떤 이름과 확장자를 사용하든지 관계는 없지만 확장자로 .C를 사용하는 것이 가장 좋다. 


4.2 소스 코드의 컴파일

여러분은 C 언어로 작성된 소스 코드를 이해할 수 있겠지만 컴퓨터는 결코 소스 코드를 이해할 수 없을 것이다. 대신, 컴퓨터는 기계어(machine language)로 작성된 명령문을 요구한다. 그래서 C 언어로 작성된 프로그램이 컴퓨터 상에서 실행될 수 있으려면, 우선 소스 코드에서 기계어로 변환될 필요가 있는 것이다. 프로그램 개발 과정의 두 번째 단계인 변환 작업은 컴파일러라는 프로그램에 의해서 수행된다. 컴파일러는 소스 파일을 입력받아서 대응하는 기계어 명령문을 작성하여 디스크 파일로 저장한다. 컴파일러에 의해서 생성되는 기계어 명령문을 오브젝트 코드(object code)라고 하며, 오브젝트 코드가 포함되어 있는 디스크 상의 파일을 오브젝트 파일(object file)이라고 한다. 각각의 컴파일러에서 오브젝트 코드를 생성하기 위해서는 정해진 명령을 사용해야 한다. 대개 소스 코드를 컴파일하기 위해서는 컴파일러의 이름과 함께 소스 파일의 이름을 입력하게 된다. 다음은 다양한 DOS/윈도우용 컴파일러에서 RADIUS.C라는 소스 파일을 컴파일하기 위해서 필요한 명령의 예이다. 


  컴파일러

  명   령

Microsoft C

cl radius.c

Borland's Turbo C

tcc radius.c

Borland C

bcc radius.c

Zortec C

ztc radius.c


RADIUS.C 파일을 UNIX에서 컴파일하기 위해서는 다음과 같은 명령을 사용하기 바란다.

cc radius.c 

실제로 여러분의 컴파일러에서 사용되는 정확한 명령을 알아보기 위해서는 제공되는 컴파일러 설명서를 참조하기 바란다. 만약 그래픽 개발 환경을 사용 중이라면 컴파일 작업은 훨씬 더 쉬어진다. 대부분의 그래픽 환경에서는 컴파일 아이콘을 선택하거나 또는 메뉴에서 특정 항목을 선택하여 프로그램 리스트를 컴파일할 수 있다. 일단 코드가 컴파일되면 실행 아이콘을 선택하거나 메뉴에서 특정 항목을 선택하는 것만으로 프로그램을 실행할 수 있다. 프로그램을 컴파일하고 실행하는 방법에 대해서는 여러분이 사용 중인 컴파일러의 사용 설명서 참조하기 바란다. 소스 파일을 컴파일하게 되면 오브젝트 파일이 생성된다. 그래서 컴파일을 수행한 디렉토리의 파일 목록을 살펴보면, 소스 파일과 동일한 이름을 가지고 있지만 .C가 아니라 .OBJ라는 확장자를 가지는 파일을 볼 수 있을 것이다. .OBJ의 확장자를 가지는 파이은 오브젝트 파일이며 링커에 의해서 사용된다. UNIX 시스템의 경우 컴파일러는 .OBJ의 확장자가 아니라 .O의 확장자를 가지는 오브젝트 파일을 생성할 것이다. 


4.3 실행 파일을 생성하기 위한 링크 작업


프로그램을 실행하기 위해서는 다른 한 가지 단계가 더 필요하다. 

C 컴파일러에서는 오브젝트 코드를 가지고 있는 함수 라이브러리(function library)가 함께 제공된다. 오브젝트 코드는 컴파일된 상태의 코드를 말한다. 내장 함수는 컴파일러를 제작한 회사에서 따로 작성한 C 코드를 통해서 생성된 것이며, 컴파일러를 구입할 때 사용할 수 있는 상태로 함께 제공되는 것이다. 앞에서 예제를 설명할 때 사용된 printf() 함수는 라이브러리 함수의 하나이다. 이런 라이브러리 함수는 화면에 자료를 출력하거나 디스크 파일에서 데이터를 읽어들이는 것과 같이 프로그램에서 흔히 요구되는 동작을 수행하기 위해서 사용된다. 프로그래머가 작성한 프로그램에서 이런 내장 라이브러리 함수를 전혀 사용하지 않는 경우는 거의 없으며, 이런 함수를 사용하는 프로그램을 작성했다면 소스 코드를 컴파일하여 생성되는 오브젝트 파일은 마지막 단계인 실행 가능한 프로그램을 생성하기 위해서 함수 라이브러리 내의 오브젝트 코드와 결합되어야 한다. '실행이 가능하다(executable)'는 것은 프로그램을 컴퓨터에서 실행하거나 사용할 수 있다는 것을 뜻한다. 이것을 링크(linking) 과정이라고 하며, 짐작할 수 있듯이 링커(linker) 라는 프로그램에 의해서 수행된다.


4.4 프로그램 개발 과정의 완료

일단 프로그램이 컴파일되고 실행 가능한 파일을 생성하기 위해 링크 과정을 거치게 되면, 사용자는 시스템 프롬프트에서 파일 이름을 입력하거나 또는 다른 어떤 프로그램을 사용하는 것과 같은 방법으로 실행할 수 있다. 만약 프로그램을 실행할 때 예상했던 것과 다른 결과가 나타난다면 다시 첫 번째 단계로 돌아갈 수 있을 것이다. 프로그래머는 문제가 발생한 부분을 확인하고, 소스 코드에서 문제를 해결해야 한다. 소스 코드의 내용이 변경될 때에는 실행 가능한 파일의 내용도 정정하기 위해서 프로그램을 다시 컴파일하고 링크할 필요가 있다. 이런 과정은 예상했던 결과가 나타날 때까지 반복되어야 한다. 마지막으로, 컴파일과 링크 과정에 대해 알아둘 사항이 있다. 여기에서는 컴파일과 링크 과정을 두 개의 독립된 단계로 설명했지만 이런 두 가지 과정을 한번에 수행한다. 그러나 컴파일과 링크 과정이 비록 하나의 명령을 통해서 동시에 수행되더라도 수행 방법에 관계없이 이런 과정은 두 개의 독립된 과정이라는 것을 기억하기 바란다


5. 간단한 C 예제 프로그램

이제 여러분은 C 언어를 사용하여 프로그램을 작성해 보기 원할 것이다. 여기에서는 컴파일러의 사용법을 익힐 수 있도록 도와주기 위해서 간단한 프로그램의 개발 과정을 설명할 것이다. 여기서 설명하는 모든 기술적인 내용을 이해할 수는 없겠지만, 예제를 통해서 C 프로그램을 작성하고 컴파일하여 실행하는 과정에 대해서 충분히 이해할 수 있을 것이다. 예제에서는 문장 'Nice guy!'를 화면 상에 출력하는 NICE.C라는 간단한 프로그램을 사용한다. 리스트 1.1 에는 NICE.C의 소스 코드가 나타나 있다. 리스트를 입력할 때 문장 번호나 콜론을 입력할 필요는 없다. 

리스트 1.1> NICE.C

    #include <stdio.h>


    main()

    {

        printf("Nice guy!");

        return 0;

    }



우선, 설명서를 참조하여 컴파일러를 정확히 설치했는지 확인하기 바란다. UNIX, DOS 또는 어떤 운영체제를 사용하든지, 여러분의 사용 환경에서 컴파일러와 에디터를 사용하는 정확한 방법을 알아두기 바란다. 컴파일러와 에디터를 사용할 준비가 되었다면, NICE.C를 입력하고 컴파일하여 실행하기 위해서 다음과 같은 단계를 따르도록 한다 .


5.1 NICE.C의 입력과 컴파일

NICE.C 프로그램을 입력하고 컴파일하기 위해 다음과 같이 한다. 

a. C프로그램이 저장되어 있는 디렉토리로 이동하거나 또는 C 프로그램의 경로를 검색 경로에 추가하고 나서 에디터를 실행한다. 앞에서도 설명했듯이, 원한다면 어떤 텍스트 에디터든지 사용할 수 있지만, 볼랜드의 Turbo C++나 마이크로소프트의 Visual C/C++와 같은 최신의 C 컴파일러에서는 하나의 환경에서 프로그램을 입력하고, 컴파일하고, 링크할 수 있도록 해주는 편리한 통합 개발환경(IDE : Integrated Development Environment) 을 제공해준다. 여러분의 컴파일러에서 IDE가 제공되는지 알아보기 위해서 설명서를 확인하기 바란다. 

b. 키보드를 사용하여 앞의 <리스트 1.1>에 나타난 것과 동일하게 NICE.C의 소스 코드를 입력한다. 각 문장의 마지막 부분에서는 Enter를 누른다. 

c. 소스 코드를 저장한다. 파일의 이름은 NICE.C라고 지정한다. 

d. 디렉토리나 폴더의 파일을 나열하여 NICE.C가 디스크에 저장되어 있는지 확인한다. 

e. NICE.C를 컴파일하고 링크한다. 여러분의 컴파일러 설명서에 나타나 있는 명령을 사용하면 된다. 아무런 에러나 경고 사항이 없다고 알려주는 메시지가 출력되어야 한다. 

f. 컴파일러의 메시지를 확인한다. 만약 아무런 에러나 경고 메시지도 나타나지 않는다면 모든 것이 정상적이라고 할 수 있다. 만약 프로그램을 입력할 때 실수를 했다면, 컴파일러는 문제를 찾아서 화면 상에 적절한 에러 메시지를 출력할 것이다. 예를 들어, 단어 printf를 잘못하여 prntf로 입력했다면 다음과 비슷한 메시지가 출력될 것이다


Error : undefined symbols:_prntf in nice.c (nice.OBJ) 


g. 이런 에러 메시지나 다른 어떤 메시지가 출력된다면 2단계로 돌아가야 한다. 그리고 에디터를 실행하고 NICE.C를 읽어들여서 파일의 내용을 리스트 1.1과 주의 깊게 비교하여 필요한 내용을 정정하고 3단계부터 다시 진행한다

h. 이제 첫 번째 C 프로그램이 컴파일되고 실행할 수 있는 상태가 되었을 것이다. 만약 디렉토리에서 확장자에 관계없이 NICE라는 이름을 가지는 모든 파일의 목록을 확인한다면, 다음과 같은 내용을 볼 수 있을 것이다. 

- NICE.C - 에디터를 사용하여 입력한 소스 코드 파일

- NICE.OBJ 또는 NICE.O - NICE.C의 오브젝트 코드가 저장된 파일

- NICE.EXE - NICE.C를 컴파일하고 나서 링크하여 생성된 실행 가능한 프로그램


i. NICE.EXE를 실행하거나 사용하기 위해서 간단히 nice를 입력한다. 'Nice guy!'라는 문장이 화면에 출력될 것이다. 정상적으로 프로그램이 실행되었다면 축하할 일이다. 여러분은 첫 번째 C 프로그램을 입력하고 컴파일하여 실행해보았다. NICE.C는 특별히 유용한 어떤 동작을 수행하지 않는 간단한 프로그램이지만 프로그래밍을 시작하는 아주 좋은 예이다 실제로, 오늘날의 대부분의 전문적인 C 프로그래머는 이런 과정을 거쳐서 NICE.C를 컴파일하여 C를 배우기 시작했으므로, 여러분은 앞으로 뛰어난 프로그래머가 될 수 있다는 희망을 가질 필요가 있다.

▶ 컴파일에러

컴파일에러(compilation error)는 컴파일러가 컴파일할 수 없는 어떤 내용을 소스 코드 내에서 발견할 때 발생하는 에러이다. 컴파일에러는 소스를 잘못 입력하거나 구두점을 빠뜨리고, 또는 다른 어떤 실수로 인해서 발생한다. 다행히, 현재 사용되는 컴파일러는 잘못된 부분에서 작업을 포기하지 않고 에러의 내용과 위치를 알려준다. 이런 기능은 소스 코드의 에러를 찾아서 정정하기 쉽게 도와준다. NICE.C에 잘못된 내용을 고의로 포함시켜 컴파일에러를 살펴보도록 하겠다. 앞에서 NICE.C를 입력하여 실행해 보았으므로 디스크에는 NICE.C라는 파일이 저장되어 있을 것이다. 에디터를 실행하고 printf() 함수가 사용된 곳으로 커서를 이동시키고 문장의 마지막에서 세미콜론(;)을 제거한다. 이제 NICE.C는 <리스트 1.2>와 같은 내용이 될 것이다. 

리스트 1.2 에러가 포함된 NICE.C

     1: #include <stdio.h>

     2:

     3: main()

     4: {

     5:    printf("Nice guy!")

     6:    return 0;

     7: }


다시 파일을 저장한다. 이제 파일을 컴파일할 수 있을 것이다. 컴파일러 명령을 입력하여 파일을 컴파일하자. 여기에서는 고의로 에러를 만들었기 때문에 컴파일은 정상적으로 수행되지 않을 것이다. 대신에 화면에는 다음과 같은 메시지가 출력될 것이다.

nice.c(6) : Error: ';' expected 

이것은 다음과 같이 세 부분으로 나누어 볼 수 있다.

>nice.c              - 에러가 발생한 파일의 이름

(6)                - 에러가 발생한 문장 번호

Error: ';' expected - 에러의 내용


앞에서 발생한 에러는 NICE.C의 6번째 줄에서 세미콜론이 발견되어야 하지만 컴파일러가 세미콜론을 발견할 수 없었다는 것을 상세하게 알려주고 있다. 그러나 실제로는 소스 코드의 5번째 줄에서 세미콜론이 생략되었으므로 발견된 에러와 사실에는 차이가 있다는 것을 알 수 있다. 여기에서, 컴파일러가 5번째 줄에서 생략된 세미콜론을 6번째 줄에서 생략된 것으로 받아들이는 이유는 무엇일까? 해답은 c 언어가 각 줄을 정확히 '구분하지 못한다.'는 데 있다. 세미콜론을 함수와 분리하여 그 다음 줄에 입력하는 것은 좋지 못한 습관이지만, printf() 함수의 다음 줄에 세미콜론이 사용될 수도 있을 것이다. 컴파일러는 6번째 줄에서 다음 명령인 return을 발견하고 나서야 앞에서 세미콜론이 생략되었다는 것을 알게 된다. 그래서 컴파일러는 에러가 6번째 줄에서 발생했다고 알려주는 것이다. 여기서 C 컴파일러와 에러 메시지에 대한 중요한 사실을 알 수 있다. 컴파일러는 에러를 발견하고 찾아내는 일에 대해서 상당히 영리하게 동작하지만 그 결과가 항상 정확하지는 않다. 프로그래머는 가끔 컴파일러가 출력하는 에러 메시지를 읽고 에러의 정확한 위치를 찾기 위해서 C에 대해서 알고 있는 지식을 응용해야 할 것이다. 실제로, 컴파일러가 발견하는 에러의 위치가 정확하지 않다면 대부분의 경우에는 바로 앞 문자에서 발생한 것이다. 처음에는 이런 문제로 인해 에러를 발견하는 것이 어려울 수도 있겠지만 곧 에러의 위치를 쉽게 찾을 수 있게 될 것이다.

'C 언어' 카테고리의 다른 글

2장 C 프로그램의 구성 요소  (0) 2019.06.02
3장 데이터 저장하기 : 변수와 상수  (0) 2019.06.02
4장 문장, 수식, 연산자  (0) 2019.06.02
5장 함수의 기본  (0) 2019.06.02
6장 기본적인 프로그램 제어문  (0) 2019.06.02

+ Recent posts