C언어에 대해 공부하기전, 컴퓨터, 프로그램의 역사에 대해 알아보고, 기본적인 용어에 대해 배워보고자 한다.
이는, 앞으로의 모든 언어 공부에 도움이 되기에 넘어가지 말고 배우는 것을 추천한다.
<컴퓨터와 프로그래밍>
컴퓨터의 기본적인 임무는 숫자 계산을 빠르게 하는 것이다. 하지만 계산만 빨리 할 수 있다고 해서 컴퓨터라고 부를 수 있는가?
요즘의 컴퓨터는 단지 계산만 하는 기계는 아니다.
컴퓨터란 명령어(instruction)들의 리스트에 따라 데이터를 처리하는 기계이다.
특정한 작업을 수행하도록 설계된 명령들의 리스트가 바로 프로그램(program)이다. 다양한 프로그램을 수행할 수 있는 능력은 컴퓨터를 범용적인 다재다능한 기계로 만들었으며 이것이 계산기와 컴퓨터를 구별하는 특징이 된다.
프로그래밍이 가능한 최초의 기계는 ‘컴퓨터의 아버지’로 불리는 찰스 배비지가 만든 ‘해석 기관(Analytical Engine)’이다. 배비지는 범용적인 계산 기계를만들기 위하여 해석 기관을 설계하였다.
해석 기관은 모든 종류의 계산을 하나의 기계에서 할 수 있도록 설계된 최초의 범용 컴퓨터이다.
이전의 기계와 달랐던 점은 해석 기관에서는 프로그램을 작성하는 것이 가능했다는 점이다.
하지만, 해석 기관은 개념과 원리만 완성됐을 뿐 실제로 만들어지지 못했다.
배비지의 해석기관의 4가지 핵심적인 요소(component)
1. 중앙 처리 장치(계산을 담당, mill이라고 불림)
2. 기억장치(중간 단계에서 임시적으로 숫자를 저장, store라고 불림)
3. 출력 장치(출력 숫자를 나타내는 다이얼)
4. 입력 장치(천공 카드 = 데이터를 표현하기 위해 규칙에 따라 직사각형 모양의 구멍을 뚫어 사용하는 종이카드)
<최초의 전자식 컴퓨터>
19세기 말까지 실용적인 컴퓨터를 구현할 수 있는 많은 요소 기술들이 등장했다.
펀치카드, 부울 대수, 진공관, 텔레타이프 등이 있다.
전자 공학의 발전으로 전자 스위치가 부울 대수(Boolean algebra)의 참/거짓을 나타낼 수 있다는 것을 깨닫게 되고, 최초의 전자식 컴퓨터 ENIAC이 개발된다.
ENIAC은 십진법을 사용해서 계산을 하는 최초의 범용 전자 컴퓨터였다.
산술 연산과 논리 연산을 수행할 수 있었고 변수 개념도 지원하였다. 하지만, 결정적인 문제점은 탄도 궤도 표를 계산하는 특수 목적 컴퓨터였기 대문에 설계된 목적만을 수행할 수 있었고, 다른 연산을 수행시키려면 아주 복잡했다.
몇몇 ENIAC의 개발자들이 그 결점을 개선하려고 노력하였고 후에 프로그램 내장(stored program)구조 또는 폰 노이만 구조를 설계한다.
이 프로그램 내장 방식은 폰 노이만이 1945년에 발표한 논문에서 최초로 기술되었다. 프로그램 내장 구조란 프로그램을 메모리에 저장하는 방식이다.
이후 최초의 실용적인 프로그램 내장 방식의 컴퓨터인 EDVAC이 1948년에 제작된다. EDVAC은 최초로 메모리를 가지고 있었고 이 메모리 안에 프로그램을 내장하여 수행했다. EDVAC은 0과 1의 이진 숫자들로 구성된 기계어를 사용했다.
폰 노이만 구조의 특징
1. 프로그램과 데이터가 모두 메인 메모리에 저장됨
2. 메인 메모리에 저장된 프로그램에서. 이진수로 되어 있는 명령어들을 순차적으로 가져와서 실행함
즉, 프로그램이란 컴퓨터에 반드시 있어야 되는 것이며, 우리가 하고자 하는 작업을 컴퓨터에게 전달하여 주는 역할을 하는 것이다.
기계어 : 0과1로 구성되어있는 이진수 형태의 언어.
하지만 기계어는 인간이게 상당히 불편한 언어이기에 인간의 언어에 근접한 프로그래밍 언어들을 만듦.
그래서 인간이 프로그래밍 언어를 배워서 프로그램을 작성하면 컴파일러라고 하는 통역을 담당하는 소프트웨어가 프로그램을 기계어로 바꾸어줌.(통역과 비슷)
코딩의 진행 순서 : 프로그래밍 언어 -> 컴파일러 -> 기계어
프로그램을 전문적으로 작성하는 사람을 프로그래머(programmer)라고 한다.
역사상 최초의 프로그래머는 에이다 러브레이스(Ada Lovelace)이다. 그녀는 현대적인 컴퓨터가 나오기 100년 전에 이미 서브루틴(subroutine), 루프(loop), 점프(jump) 등의 핵심적인 컴퓨터 프로그래밍 기본 원리를 고안했다.
에이다 러브레이스(Ada Lovelace)의 핵심적인 컴퓨터 프로그래밍 기본원리
서브루틴 : 같은 공식을 여러 번 사용
루프 : 같은 계산 반복
점프 : 중간의 필요 없는 과정을 생략
<프로그래밍 언어>
프로그래밍 언어는 굉장히 많지만, 이들 언어들은 대개 다음의 세 가지로 분류할 수 있다.
프로그래밍 언어의 세 가지 분류
1. 기계어(machine language)
2. 어셈블리어(assembly language)
3. 고급 언어(high-level language)
(1) 기계어
컴퓨터가 바로 이해할 수 있는 단 하나의 언어.
기계어는 특정 컴퓨터의 명령어(instruction)를 이진수로 표시한 것이며 컴퓨터 하드웨어를 설계할 때 결정된다. 기계어는 하드웨어에 따라 달라지기 대문에 철저히 하드웨어에 종속된다. 이것이 인텔의 CPU를 사용하는 프로그램은 ARM의 CPU를 사용하는 컴퓨터에서 바로 실행시키지 못하는 이유이다.
(2) 어셈블리어
어셈블리 언어를 사용하면 프로그래머들은 CPU의 명령어들을 기호(Symbolic name)로 표기할 수 있었다.
어셈블리 언어는 프로그래머가 기계어보다는 더 높은 수준에서 프로그램을 작성하는 것을 가능하게 한다.
어셈블러라는 프로그램이 기호를 이진수로 변환하는 식으로 작동한다.
어셈블리 프로그램에서는 기호 이름과 CPU의 명령어가 일대일 대응된다. 즉, 컴퓨터의 CPU가 달라지면 실행이 불가능하다.(=저급언어 / low level language)
(3) 고급 언어
어셈블리어가 기계어보다는 편리하지만 인간이 사용하기에는 번잡한 언어였다.
간단한 작업을 하려고 해도 많은 명령어를 기호로 기술하여야 했기 때문이다.
이러한 목적으로 고급 언어가 개발된다.
고급 언어의 개발로 프로그램을 개발하는 프로그래머들은 더 이상 특정한 컴퓨터의 구조에 얽매이지 않아도 되었다. 고급 언어에서의 연산들은 특정한 컴퓨터의 명령어 집합보다는 훨씬 고수준이기 때문이다. 그렇기에 특정 컴퓨터의 구조나 프로세서에 무관하게, 독립적으로 프로그램을 작성할 수 있었다.
EX) C, C++, JAVA 등
<C언어의 역사>
C언어는 1969년과 1973년에 걸쳐서 AT&T의 벨연구소에서 Dennis Ritchie에 의하여 탄생했다. ‘C’라고 하는 이름의 유래는 직전에 만들어진 언어의 이름이 ‘B’였기 때문이다.
C언어는 UNIX운영체제를 개발하기 위하여 만들어졌기 때문에 UNIX라는 운영체제의 탄생과도 밀접한 관계가 있다.
Ken Thomson과 Dennis Ritchie가 UNIX와 C언어를 개발하게 된 동기는 알려진 바로는 ‘Space Travel’이라고 하는 게임을 하기 위해서라고 한다. ‘Space Travel’은 회사의 메인 프레임에서 돌아갔었지만 너무 느렸기 때문에 PDP-11이라는 사무실에 있었던 미니컴퓨터에 이식하기로 한다. 하지만 PDP-11은 운영체제가 없었고 따라서 운영체제를 작성하기로 하였는데 모든 코드를 어셈블리 언어로 작성하기에는 너무 어렵고 지루하였다.
두 사람은 운영체제를 고수준의 언어로 작성하여 운영체제가 한 번 작성되면 다른 컴퓨터에 쉽게 이식하는 것이 필요하다고 생각하게 되었고 언어’B’에 관심을 가진다. 하지만 언어 ‘B’는 당시 최신 컴퓨터였단 PDP-11의 성능을 충분히 활용하기에는 모자란 점이 있다고 판단하였고 그렇게 UNIX 커널을 ‘C’언어로 다시 작성한다.
Dennis Ritchie는 이 공로로 1983년에 Ken Thomson과 함께 컴퓨터 분야의 노벨상이라고 불리는 Turing상을 수상한다.
C언어의 특징
1. 간결한 언어
2. 효율적인 언어
3. 저수준, 고수준의 프로그래밍 전부 가능(low level, high level)
4. 뛰어난 이식성 : 한번 작성된 프로그램을 다른 CPU를 가지는 하드웨어로 쉽게 이식할 수 있다. 즉, PC에서 개발된 프로그램
도 컴파일만 다시 하면 슈퍼컴퓨터에서도 수행시킬 수 있다.
5. 초보자가 배우기 어렵다.
<알고리즘(Algorithm)>
알고리즘은 요리를 만들기 위해 오븐을 준비했을 때, ‘요리를 어떻게 만드는가’에 해당한다.
주어진문제를 어떤 절차에 따라서 해결할 것인가가 빠져있으면 프로그램을 작성할 수 없다. 즉, 문제를 해결하는 절차 혹은 방법이 바로 알고리즘이다.
알고리즘을 기술하는 3가지 방법
1. 영어와 국어같은 자연어
2. 순서도(flowchart)
3. 의사 코드(pseudo-code)
[의사코드란 프로그램 코드를 작성할 때 사용하기 위해, 프로그램의 진행 과정을 단계별로 기록해 놓은 것.
가짜의(Pseudo) - 코드 로써, 알고리즘이 수행될 내용을 인간의 언어로 간략히 설명해 놓은것을 말한다.]
알고리즘의 입문단계 추천 방법
1. 입문단계에서는 순서도를 사용하는 것이 좋다.
2. 항상 순서도를 통해 자신의 논리를 가시화 하는 것이 좋다.
3. 수행의 시작 – 처리/판단/연결자/입출력 – 수행의 종료 순서로 하는 것이 좋다.
단, 순서도의 단점은 알고리즘이 복잡해질 경우 기술하기가 힘들어진다는 점 명시할 것.
자료구조와 알고리즘 분야에서 알고리즘을 본격적으로 학습하는 것도 좋은 방법이다.
간단한 지침을 주자면, ‘문제를 한 번에 해결하려고 하지 말고 더 작은 크기의 문제들로 분해한다. 문제가 충분히 작아질 때까지 계속해서 분해한다.'를 기억하면 좋다.
<프로그램 개발 과정>
1. 요구 사항 분석
2. 알고리즘의 개발
3. 소스 작성
4. 컴파일과 링크
- 컴파일 : 소스 파일의 문작을 분석하여 문법에 맞도록 작성되었는지를 체크. 만약 오류가 발견되면, 사용자에게 오류를 통보하고 컴파일은 종료된다. 오류가 없다면 컴파일러는 각 문장들을 기계어로 변환된다. 이 기계어 파일은 오브젝트 파일(object file)이라고 불린다. 윈도우즈에서는 ‘.obj’확장자를 가진다.
- 링크 : 오브젝트 파일들을 라이브러리와 연결하여 실행프로그램을 만든다. [라이브러리(library)란 프로그래머들이 많이 사용되는 기능을 미리 작성해 놓은 것으로 컴파일러에 내장되어있다.] 링크를 수행하는 프로그램을 링커(linker)라고 하며, 윈도우즈에서는 test.obj 파일에 라이브러리를 붙여서 실행 가능한 파일인 test.exe가 생성된다.
- 에디터(editer) -> 소스코드(test.c) -> 컴파일러(compiler) -> 오브젝트 파일(test.obj) -> 링커(linker) -> 실행파일(test.exe) -> 실행(execution)
5. 실행과 디버깅
- 실행 : 프로그램이 실행 파일로 만들어져서 성공적으로 실행되기만 해서 모든 작업이 끝난 것은 아니다. 문법적인 오류가 없더라도 우리가 설계한대로 실행되지 않을 수 있다. 이 처럼 컴파일 오류는 없지만 알고리즘을 잘못 생각하여 의도했던 대로 실행되지 않는 경우를 논리적인 오류(logical error)라고 한다. 논리적인 오류란 문법은 틀리지 않았으나 논리적으로 정확하지 않음을 의미한다.
- 디버깅 : 의도했던 대로 프로그램이 동작하지 않으면 소스 프로그램을 수정하고 다시 ‘컴파일’ -> ‘링크’ -> ‘실행’의 단계를 거쳐야 한다. 이러한 오류 수정 작업을 보통 디버깅(debugging)이라 하고, 이때 사용되는 도구를 디버거라고 한다. 디버깅에서 버그(bug)는 벌레를 뜻하며, 디버그(debug)는 해충을 잡는다는 뜻이다. 이 말은 프로그램의 오류를 벌레에 비유해 오류를 찾아 수정하는 일이라는 의미로 쓰인다.
6. 유지 보수
<통합 개발 환경>
예전에는 에디터, 컴파일러, 디버거 등이 별도의 분리된 프로그램이었다. 따라서 프로그래머들은 매번 여러 개의 프로그램을 반복적으로 수행시켜야 했다. 통합 개발 환경(IDE : intergrated development environment)과 같은 소프트웨어 도구들이 등장하면서 우리는 더욱 간편하고 효율적을 프로그램을 작성할 수 있게 되었다. IDE는 프로그램 개발에 필수적인 편집, 컴파일, 실행, 디버깅 기능을 하나로 통합한 도구이다.
많이 사용되는 IDE(통합 개발 환경)
1. Visual Studio
2. 이클립스
4. Vscode
'IT > C언어' 카테고리의 다른 글
[C언어 튜토리얼] 맥에서 C언어 개발환경 구축하기(M1 맥북 프로) (3) | 2021.08.08 |
---|