Linear Algebra
📚

Introduction to C++

현대 사회에서 컴퓨터는 압도적으로 빠르지만, 컴퓨터는 제한된 수의 명령만 이해할 수 있습니다. 컴퓨터 프로그램(application)은 컴퓨터가 특정 task를 수행하기 위해 컴퓨터가 수행할수 있는 명령어의 집합을 말합니다. 이러한 프로그램을 만드는 과정을 프로그래밍이라고 합니다. 프로그래밍 한다는 것은 여러 개의 text file로 이루어진 명령어 모음집(Source Code)을 작성하는 것을 말합니다.

컴퓨터가 쓰는 언어, 사람이 쓰는 언어

machine Language는 컴퓨터가 사용하는 언어를 말합니다. 컴퓨터는 오직 기계어를 통해서만 명령어를 이해할 수 있으며, 기계어는 0과 1로만 이루어져 있습니다.
10110000 01100001
VHDL
복사
이렇게 0,1로만 이루어진 2진수 명령어는 사람이 이해하기 굉장히 어렵습니다. 각 지점마다의 숫자가 의미하는 것이 무엇인지 알아야만 프로그래밍이 가능한데, 각 의미를 외우는 것은 현실적으로 힘듭니다.
이러한 숫자의 의미를 사람이 이해하기 쉽게 단어 형태로 변경한 언어가 어셈블리어 입니다. 예를 들면, 1000 1011은 ‘mov’ 라는 단어로 치환하여 사용합니다. 전체 형식은 그대로이지만, 특정 숫자를 특정 명령 단어로 바꿈으로써 좀 더 사람이 보기 편한 형태가 됩니다.
앞서 보여드린 기계어 예시를 어셈블리 언어로 치환하면 아래와 같습니다.
mov al, 061h
VHDL
복사
이렇게 함으로써 어셈블리어는 기계어보다 훨씬 더 쉽게 이해하고 작성할 수 있습니다. 하지만 컴퓨터는 이 어셈블리어를 바로 이해할 수 없기 때문에 실행 되기 전에 기계어로 번역이 필요합니다. 이 때 사용하는 프로그램이 바로 Assembler입니다.
그럼에도 어셈블리어는 여전히 단점을 가지고 있습니다.
기계어보다는 읽기 쉽지만 여전히 사람이 읽기 쉽지 않고(가독성 문제) 작성된 코드를 이해하더라도 실제 프로그램이 수행되는 작업을 이해하기는 어렵습니다. 또한 한 CPU에 해당하는 어셈블리 언어로 작성된 프로그램이 다른 하드웨어서 작동하지 않을 수도 있어서 수정이 필요합니다 (이식성 문제).
이러한 문제를 해결하기 위해 C,C++,Java 등등의 새로운 프로그래밍 언어가 개발되었고 컴퓨터 종류와 상관 없이 프로그램을 작성할 수 있도록 설계할 수 있게 되었습니다. 이를 High-level Language라고 합니다.
앞서 보여드린 기계어, 어셈블리어 코드에 대응하는 고급언어는 아래와 같습니다.
a = 97;
C
복사
고급 언어로 작성된 프로그램들 역시 컴퓨터가 이해할 수 있는 형식으로 바뀌어야 합니다. 이를 행하는 방법은 크게 2가지 있습니다. 바로 Compile과 Interpreter입니다.
Compiler는 소스 코드를 독립적으로 실행할 수 있는 프로그램을 만드는 프로그램입니다. 한번 코드가 실행 파일로 바뀌면 더 이상 컴파일러는 필요하지 않습니다. 아래 그림은 컴파일 과정을 도식화한 그림입니다.
우리가 다룰 C++가 여기 속하게 됩니다.
이와 다르게, 실행 파일로 컴파일 하는 것이 아니라, 소스코드의 명령을 직접 실행하는 프로그램이 바로 Interpreter 입니다. 컴파일러보다 유연하게 작성할 수 있지만, 매번 프로그램을 실행할 때마다 interpreting 과정이 필요하기 때문에 효율적이지 않습니다. 인터프리팅 과정을 도식화하면 아래와 같습니다.
일단 고급언어로 작성이 되면, 다른 하드웨어에 대해서 프로그램을 변경하지 않아도 됩니다. 각 CPU에 대해서 다시 컴파일 하기만 하면 됩니다. → 이식성 증가!

C++ 프로그램은 어떻게 개발하나요?

본격적으로 프로그램을 짜기 앞서, 어떻게 C++ 프로그램이 개발되는지 살펴볼 필요가 있습니다. 아래 그림은 그 과정을 설명하는 간단한 도식입니다.

1단계. 해결하려는 것이 무엇인지 정하기

해결하고 싶은 문제가 어떤 것인지 파악해야 합니다. 무엇을 만들 것인지 고민해보는 과정입니다.
“ 많은 숫자를 입력한 다음 평균을 계산할 수 있는 프로그램을 작성하고 싶습니다. “
"저는 주가 파일을 읽고 주가가 오를지 내릴지를 예측하는 프로그램을 작성하고 싶습니다."

2단계. 문제를 어떻게 해결할지 결정하기

“어떻게” 문제를 해결할지 고민해 보아야 합니다. 보통 좋은 해결책들은 간단하고, 문서화가 잘 되어 있고, 모듈화 되어 있는 경우가 많습니다.

3단계. 프로그램 작성하기

프로그래밍 언어에 대한 지식과 프로그림을 편집할 텍스트 편집기를 이용해 작성합니다. 앞으로 작성될 포스팅들은 이 과정을 설명합니다.
복잡한 C++ 프로그램의 경우 여러 개의 .cpp \text {.cpp }파일이 존재합니다.

4단계. 소스코드 컴파일 하기

C++ 프로그램을 컴파일 하기 위해 C++ 컴파일러를 이용합니다. 컴파일러는 2가지 중요 작업을 수행합니다!
작성된 코드가 C++ 언어의 규칙을 따르는지 확인합니다 문법적으로 잘못 된 부분이 있어 수정이 필요한 부분을 찾아 고쳐야 할 곳이 어딘지 (해당 줄 번호)를 제공합니다. 오류가 수정 될 때 까지 컴파일 과정도 중단 됩니다.
각각 주어진 C++ 소스 코드를 object 파일 이라는 기계어 파일로 변환합니다. object file의 이름은 일반적으로 name.o \text { name.o }또는  name.obj \text { name.obj }입니다.

5단계. object 파일과 라이브러리 연결하기

오브젝트 파일과 라이브러리를 묶는 역할을 linker가 수행하게 됩니다. library file은 다른 프로그램에서 재사용할 수 있게 패키징된 미리 컴파일 된 코드 모음을 말합니다. 이 중에서도 C++ Standard Library는 가장 자주 사용되는 라이브러리이며 작성되는 거의 대부분의 코드가 포함하고 있습니다. 이 외에도 만들고자 하는 프로그램의 성향에 따라 다른 라이브러리 또한 존재합니다.
링커가 하는 역할은 크게 3가지입니다.
컴파일러에서 생성한 object file을 가져와 단일 실행 프로그램으로 만듭니다.
링커는 오브젝트 파일과 라이브러리 파일을 연결합니다.
파일 간 종속성을 확인하고 파일을 연결합니다.
연결이 다 되면 실행 가능한 실행파일이 생성됩니다!

6~7단계. 테스트와 디버깅 하기

실행파일을 실행하여 예상한 출력과 동일한지 확인합니다. 프로그램이 잘 실행 되지 않으면 디버깅을 통해 무엇이 잘못되었는지를 알아내는 과정입니다.

Reference