교과목/프로그래밍

프로그래밍 보고서(전처리기, 헤더파일, 기계어, 어셈블리어, 고급 언어, 컴파일 단계)

Jubil 2017. 11. 5. 00:02
반응형

전처리기

 

 

전처리기(preprocessor), 컴파일러가 소스 파일을 컴파일하기 전에 사용자가 지시한 작업을 먼저 처리하는 것이다.

, 컴파일러보다 먼저 작업을 처리해준다. 그래서 중요한 작업은 전처리기가 하는 경우가 많다.

 

지금까지 #include를 많이 써왔는데 여기서 #은 전처리기가 작업하라고 표시하는 것이다.

include는 전처리기의 명령어 중 하나인데 include 말고도 define, if ~ endif, else, elif, ifdef, ifndef, error 등 많은 전처리기 명령어가 있다.

 

매크로는 여러 명령어를 모아놓은 것이라고 보면 된다.

매트로는 매크로 상수와 매크로 함수로 분류한다.

 

매크로 상수


#define은 매크로를 만드는 것이다.

매크로 상수, 매크로 함수 둘 다 #define으로 만든다.

이렇게 #define으로 만들어진 상수를 심볼릭 상수라고 한다.


1

2

3

4

5

6

7

8

9

#include <stdio.h>

#define PI 3.14

int main(){

printf("%lf\n", PI);

return 0;

}

cs



 

이렇게 사용하면 왜 저렇게 상수를 만들까? 하고 쓸모없다고 생각할 수 있다.

하지만 3.14 라는 값이 100, 1000, 아니면 그 이상 쓰였는데 수정을 해줘야 한다면 모두 수정해야하는 문제가 발생한다.

그런데 심볼릭 상수로 정의해 놓았다면, 선언문만 한번 고치면 해결된다.

 

, #define문 뒤에 문장의 끝을 나타내는 세미콜론( ; )이 없을까 궁금할 수 있다.

매크로는 소스 코드를 교체하는 것이다.

 


 

여기서 PI3.14; 가 치환된 것이기 때문에 6라인은 사실

1

printf("%lf\n", 3.14;);

cs

이렇게 된다. 이런 부분을 유의해야 한다.

 


 

그리고 이렇게 #undef를 써서 매크로를 해제할 수 있다.

 

 매크로 함수



 


 

이 코드는 3 * 4를 계산해 줄 것 같지만 12가 나오지 않는다.

매크로 함수도 단순 치환이기 때문에 2 + 1 * 3 + 1 = 6 이 출력된다.

 

이런 문제를 해결하기 위해서는 괄호로 묶어야 한다.

 

1

#define MUL(X, Y) ((X) * (Y))

cs

이렇게 말이다. 이런 치환의 의미라는 것만 알면 유용하게 쓸 수 있을 것 같다.

 

 

 

헤더파일

 

 

헤더파일이란, C언어 코드를 작성할 때 코드의 맨 위에 적고 문법을 사용하기 위해 참조하는 것을 말한다.

헤더파일이 없다면 문법을 사용할 수 없다.

 

헤더파일 안에는 라이브러리 함수라는 게 들어있는데

라이브러리 함수란, 프로그래머 쉽게 이용할 수 있도록 미리 만들어 놓은 다양한 기능들의 함수를 말한다.

이 라이브러리 함수를 사용하기 위해서는 그 함수의 원형과 내용이 포함되어 있는 헤더파일을 가져와야만 사용할 수 있다는 것이다.

 

#include <stdio.h>

이 헤더파일은 printf()scanf() 등 일반적으로 써야되는 문법들을 사용할 수 있게 해준다.

 

 

헤더파일의 종류

 

stdio.h

기능 : 표준 입출력 (standard input output header file)

함수 : printf(), scanf(), if(), for(), while() 등 기본적인 함수들

 

2. stdlib.h

기능 : 메모리 관리와 유용한 함수

함수 : rand(), malloc(), exit()

 

3. string.h

기능 : 문자열 처리

함수 : strcpy(), strlen(), strcmp()

 

4. time.h

기능 : 날짜와 시간

함수 : time(), asctime()

 

5. math.h

기능 : 수학, 수치계산

함수 : sin(), log(), sqrt()

 

6. ctype.h

기능 : 문자처리(판단, 변환)

함수 : isalpha(), tolower()

 

매우 많은 헤더파일 중 자주 사용하는 헤더파일들이다.

헤더파일은 어디에 사용하느냐에 따라서 가져와야 하는 헤더파일의 종류가 달라진다.

 

사용하기 편하라고 만들어 놓은 라이브러리 함수들을 많이 알면

이미 나와 있는 라이브러리 함수를 직접 구현하지 않아도 쓸 수 있다는 게 장점이다.

 

헤더파일과 라이브러리 함수를 잘 알아두도록 하자.

 

헤더파일은 #include <헤더파일명>으로 가져올 수 있다.

 

 

기계어, 어셈블리어, 고급 언어

 

 

기계어(machine language)

 

컴퓨터가 직접 읽을 수 있는 2진 숫자로 이루어진 언어를 말하며, 이는 프로그래밍 언어의 기본이 된다.

 

그러나 기계어는 이해하기 어렵고 컴퓨터 구조에 대한 충분한 지식이 없으면 프로그램 작성을 할 수 없기 때문에 범용성이 부족하고 숫자(01)를 사용함에 따라 프로그래머의 수고가 많이 필요하고 시간이 많이 걸린다.

 

기계어로 프로그램을 작성하는 것은 거의 사라졌다.

 

 

어셈블리어(assembly language)

 

이해하기 힘든 기계어의 명령부와 번지부를 사람이 이해하기 쉬운 기호와 1 : 1로 대응시켜 기호화한 프로그램 언어이다.

 

기호 언어라고도 부르며 어셈블리어로 작성된 프로그램은 어셈블러에 의해 기계어로 번역되어야만 실행이 가능하다.

 

표지부, 연산부, 피연산부로 구성된다.

 

표지부는 프로그램에서 명령들을 참조하기 위해 명령집단에 붙여지는 이름이다.

연산부는 move(이동), add(덧셈), subtract(뺄셈) 등 수행을 위한 특별한 명령들의 기호로 되어 있다.

피연산부는 데이터가 처리되어 저장될 레지스터나 저장장소를 나타낸다.

 

어셈블리어는 전자계산기에 대한 전문지식이 있어야 사용할 수 있으며, 단순한 계산으로 처리되는 업무에 적합하다.

 

 

고급 언어(high-level language)

 

컴퓨터의 하드웨어 구조와는 무관하게, 독립적으로 프로그램을 작성할 수 있는 언어이다.

 

C, FORTRAN, Pascal 등이 이에 속한다.

이들의 구성이 기계어보다는 인간의 언어에 보다 가깝기 때문에 고급 언어라고 부른다.

 

고급 언어는 프로그램을 작성하거나, 작성된 프로그램을 이해하고, 유지 보수하기가 쉽다는 게 장점이다.

하지만 프로그램이 실행되려면 반드시 컴파일러나 인터프리터 등을 이용하여 기계어로 번역되어져야 한다는 것이다.

 

 

컴파일 단계

 

컴파일에 의해 원시 프로그램을 컴퓨터가 실행할 수 있는 기계어로 번역하는 작업 단계이다.

 

전처리(processer)

-#include, #define 등의 전처리 처리

-#include 헤드파일 지정 시 <> : 기본 디렉터리 “ ” : 현재 디렉터리에서 head파 일을 참조

-그 결과로 “xx.i”파일 생성

-“xx.i” 파일에는 키워드를 쓰게끔 전역함수가 설정 되어있다. ex) printf(), scanf()

-> 컴파일러(compiler)

-어셈블리어 파일 생성하는 단계 임시파일

-컴퓨터가 읽을 수 있게 숫자 등으로 치환 //치환파일을 “xx.s”로 저장

 

-> 어셈블러(assembler)

-기계어코드(“xx.s”)를 읽어서 목적코드(“xx.o”)를 생성하는 단계

 

-> 링커(Linker)

-여러개의 파일로 나누어져 있거나, 라이브러리 함수 등이 존재 할 때 서로 연결 시켜서 실행 가능한 프로그램으로 생성하는 단계

 

-> 실행파일(*.exe)

-링크단계가 끝나면 실행파일이 생성된다.

 

 

우리가 C코드를 작성하고 Ctrl + F5를 누르고 설레는 마음과 벅찬 마음이 조화를 이루고 있을 때, 이 많은 과정이 일어난다.

반응형