일반적인 C 프로그램의 개발 과정은 아래 그림의 순서로 볼 수 있다.

하나하나 짚어보자.

 

일반적인 C 프로그램의 개발 과정

 

 

1. 소스 코드 작성

개발 환경에서 제공하는 소스 코드 편집기나 Eclipse 같은 텍스트 편집기를 이용하여 C 프로그램의 소스 코드를 작성한다.

C 프로그램의 소스 코드는 .c 확장자를 갖는 일종의 텍스트 파일이다.

 

2. 전처리기 (preprocessor)

전처리기는 프로그래머가 작성한 소스 파일을 컴파일 하기 위한 소스 파일로 변환하는 기능을 제공한다.

전처리기는 보통 다른 파일을 포함(include)하거나, 소스 파일 내의 특정 문자열을 다른 문자열로 대치(replace)하거나, 조건에 따라서 코드의 일부를 컴파일하도록 또는 하지 않도록 선택하는 기능을 제공한다.

전처리기 문장은 # 으로 시작하므로 쉽게 구별할 수 있다.

 

https://coddish.tistory.com/13

 

[C] C 전처리기 (preprocessor)

1. 정의 전처리기는 소스 파일을 실제 컴파일로 보내기 전에 처리하는 소프트웨어 프로그램이다.<p id="SE-df287b01-428a-4404-a58a-32ae58b0eb6c" style="background-color: #ffffff; color: #000000; text-align: left;" data-ke-si

coddish.tistory.com

 

 

 

3. 컴파일 (compile)

컴파일러(compiler)는 소스파일을 컴파일하면서 C언어의 문법에 맞지 않는 소스 코드에 대해 컴파일 에러를 발생시킨다.

컴파일 에러가 없으면 컴파일러는 오브젝트 파일을 생성한다.

하나의 프로그램에서 여러 개의 소스 파일을 사용하는 경우,

각각의 소스 파일을 개별적으로 컴파일하므로, 소스 파일마다 오브젝트 파일이 하나씩 생성된다.

 

 

 

4. 링크 (link)

링커(linker)는 컴파일 단계에서 생성된 오브젝트 파일들을 합쳐서 하나의 실행파일을 생성한다.

또한, 링커는 프로그램에서 사용된 라이브러리를 실행파일에 연결하기도 한다.

여러 오브젝트 파일을 하나로 합치고 라이브러리를 연결하면서 잘못된 부분이 있으면 링크 에러가 발생하는데, 링크 에러는 여러 소스 파일 사이의 상관관계를 함께 파악해야 하므로 컴파일 에러에 비해 찾기가 쉽지 않다. 컴파일 에러와 링크 에러를 합쳐서 문법적인 에러라고 하는데, 문법적인 에러가 발생하면 첫 번째 단계로 돌아가 소스 파일을 수정하는 작업부터 다시 수행한다.

 

 

5. 프로그램을 실행

문법적인 에러가 없으면 실행 파일이 만들어진다.

실행 파일을 실행해서 원하는 결과를 얻을 수 있는지 확인한다.

이때 프로그램이 잘못된 실행 결과를 생성하거나 실행 중에 프로그램이 죽는 문제가 발생할 수 있는데, 이를 실행 에러 라고 한다.

 

6. 디버깅 (debugging)

실행 에러를 찾기 위해서 디버깅 하는 단계이다.

실행 에러는 프로그램의 논리가 잘못되어 발생하는 에러로 디버깅 과정을 통해서 실행 에러가 발생한 곳을 찾을 수 있다. 디버깅을 할 때는 프로그램의 실행 흐름이 올바르게 진행되는지, 프로그램 내에서 사용된 수식의 값이 맞는지 등을 살펴보고 잘못된 부분을 찾아서 수정한 다음 다시 프로그램 개발 과정을 수행한다.

 

 

 


 

 

 

각 단계를 수행하는 전처리기, 컴파일러, 링커는 개별적인 프로그램이지만 우리가 사용하는 대부분의 C 컴파일러는 세 프로그램을 하나로 묶어서 순서대로 수행하므로 C 컴파일러 안에 전처리기, 컴파일러, 링커가 내장되어 있다고 생각해도 된다.

일반적으로 빌드(build) 를 수행하면 전처리기, 컴파일, 링크가 모두 수행된다.

'C' 카테고리의 다른 글

[C] C 전처리기 (preprocessor)  (0) 2024.04.30
[C] C 언어의 역사, 특징  (0) 2024.04.30

1. 정의

 

전처리기는 소스 파일을 실제 컴파일로 보내기 전에 처리하는 소프트웨어 프로그램이다.

실제 컴파일 전에 프로그램을 변환하기 위해 C 컴파일러에서 자동으로 사용하는 매크로 프로세서이다.

더 긴 구문에 대한 간략한 약어인 매크로를 정의할 수 있기 때문에 매크로 프로세서라고 한다.

 

 
 
 

2. 간단 설명

원본 파일을 처리하는 동안 전처리기는 헤더 파일과 매크로를 정의된 파일과 값으로 바꾼다.

즉, # 으로 시작하는 line은 실제 컴파일이 시작되기 전에 처리된다.
 

전처리가 끝난 후 사전 처리된 코드는 추가 작업을 위해 컴파일러로 전송된다.

전처리기 문장은 C 문장(statement)가 아니다.

 

 

3. C 전처리기 작업(Tasks)

1. 헤더 파일 추가 (Inclusion of header files)

#include<stdio.h>는 stdio.h 파일의 원래 구현으로 대체된다.

소스 코드에서 #include 문을 제거하고 stdio.h 파일 내용을 소스 프로그램에 포함한다.

ex) #include <stdio.h>

2. 매크로 확장 (Macro expansion)

컴파일이 시작되기 전에 전처리기가 프로그램 전체에서 BUFFER_SIZE 변수를 1020으로 바꾼다.

ex) #define BUFFER_SIZE 1020

3. 조건부 컴파일 (Conditional compilation)

특별한 전처리 지시어를 사용하여 다양한 조건에 따라 프로그램의 일부를 포함하거나 제외할 수 있음

전처리기의 도움으로 소스 코드의 어느 부분을 컴파일 해야 하는지, 어떤 부분은 컴파일 하는 동안 무시해야 하는지 결정할 수 있음.

ex) #if ... , #ifdef ... , #ifndef ... , #error

4. 라인 컨트롤 (Line control)

프로그램을 사용하여 소스 파일을 중간 파일로 결합하거나 재배열한 다음 컴파일하는 경우 라인 제어를 사용하여 각 소스 라인이 원래 어디에서 왔는지 컴파일러에 알릴 수 있음

ex) #line

 

 

 

참고) GNU C 전처리기, C 호환 컴파일러 전처리기에 대한 좀 더 자세한 설명

https://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html

 

The C Preprocessor: 1. The C Preprocessor

This macro expands to the constant 1, to signify that this is ANSI Standard C. (Whether that is actually true depends on what C compiler will operate on the output from the preprocessor.) On some hosts, system include files use a different convention, wher

gcc.gnu.org

https://ee.hawaii.edu/~tep/EE160/Book/chap3/subsection2.1.3.4.html

 

3.3.4 Conditional Compilation

The third useful facility provided by the preprocessor is conditional compilation; i.e. the selection of lines of source code to be compiled and those to be ignored. While conditional compilation can be used for many purposes, we will illustrate its use wi

ee.hawaii.edu

 

'C' 카테고리의 다른 글

[C] C 프로그램 개발 과정  (0) 2024.04.30
[C] C 언어의 역사, 특징  (0) 2024.04.30

켄 톰슨(왼쪽)과 데니스 리치(오른쪽)

 

 

AT&T의 벨 연구소에서 근무하던 두 사람은 UNIX 운영체제를 개발하면서

켄 톰슨 (Kenneth Thompson)이 절차적 명령형, 구조적 컴퓨터 프로그래밍 언어인 BCPL 언어를 필요에 의해서 변형한 B 언어를 개발,

데니스 리치 (Dennis Ritchie)가 켄 톰슨의 B 언어를 개선하면서 1972년에 C 언어가 탄생하였다.

프로그래밍 언어의 역사

 

 

 

C 언어 특징 - 간결성, 이식성, 효율성

 

간결성

-> 다른 프로그래밍 언어에 비해 구문이 간결하고, 프로그램 개발에 꼭 필요한 핵심적인 기능들을 제공

이식성 (portability) 

-> 다른 언어에 비해서 이식성이 좋다.

    C는 portable programming language 이다.

    컴퓨터에서 C 코드를 작성하면 한 줄의 코드를 수정하지 않고 C를 지원하는 모든 컴퓨터에서 실행할 수 있다.

" 하드웨어나 시스템에 얽매이지 않기 때문에
   하드웨어 독립 언어 (hardware independent language),
   또는 플랫폼 독립 언어 (platform independent language) 라고 할 수 있다. "

 

효율성

-> C 프로그램은 실행 파일의 크기도 작고, 실행 속도도 빠르다.

잘 개발된 C 프로그램의 성능은 어셈블리어 프로그램의 성능과 비슷하다. 따라서 시스템 프로그램과 같은 성능 위주의 프로그램을 개발할 때, 어셈블리어 대신 C언어가 많이 사용된다.

 

'C' 카테고리의 다른 글

[C] C 프로그램 개발 과정  (0) 2024.04.30
[C] C 전처리기 (preprocessor)  (0) 2024.04.30
각 비트에 보수를 취한 후 1을 더한다.

 

 

보수를 취한다 : 0을 1로, 1을 0으로 바꾼다.

 

// 10을 -10으로

1. 
10을 2진수로 표현.
0000 0000 0000 1010

2.
각 비트를 보수 취한다.
1111 1111 1111 0101

3.
여기에 1을 더한다.
1111 1111 1111 0110

 

'이산수학' 카테고리의 다른 글

16진수 ↔ 2진수 쉽게 변환하기  (0) 2024.04.30

 

 

16진수 → 2진수

 

16진수 1자리를 이진수 4자리로 나타내면 된다.

 

예를 들어 0xab78 은

    a      b      7       8

1010 1011 0111 1000 (2)

가 된다.

 

 

 

2진수 → 16진수

반대로 2진수를 뒤에서 부터 (2의 0승부터) 4개씩 묶은 다음 그 수를 16진수 한 자리로 바꿔준다.

마지막에 4개가 안맞는 부분은 0을 채워준다.

예를들어

110101101111000 (2) 을 4자리 씩 묶으면

110 1011 0111 1000 (2) 가 되며 맨 앞에는 세 자리이므로 0을 채워준다.

0110 1011 0111 1000 (2) 을 16진수로 하나씩 바꿔준다.

   6       b      7      8

이므로 C 표기법으로 나타내면 0x6b78 이 된다.

 

Nibble

2진수를 4비트씩 묶는 것을 니블(nibble) 이라고 하며

1byte는 2개의 nibble로 이루어져 있다.

1개의 니블이 16진수의 한 자리인 것이다.

 

'이산수학' 카테고리의 다른 글

2의 보수 (2's compliment)  (0) 2024.04.30

컴퓨터 시스템은 기계어를 사용하지만 사람은 자연어를 사용한다.

기계어 (machine language) : 0과 1로 된 CPU 명령어 (instruction)

자연어 (natural language) : 사람이 일상적으로 쓰는 언어

컴퓨터가 처음 등장했을 때에는 사람이 직접 기계어로 코딩을 했다.

사람이 0과 1로 코딩을 하는 것은 매우 어려웠고 실수가 자주 발생할 수 밖에 없었다.

그래서 등장하게 된 것이 어셈블리어 (assembly language)이다.

어셈블리어 (assembly language) : 0과 1로 되어있는 기계어의 각 명령어에 대하여 알아보기 쉽도록 니모닉 기호(mnemonic symbol)를 정해두고 사용

ex) 1011000001100001 -> mov a1, 61h

 

 

mnemonic 뜻

 

 

 

어셈블리어로 작성한 프로그램은 어셈블러(assembler)라는 프로그램에 의해서 기계어로 변환된다.

어셈블리어는 컴퓨터 시스템의 CPU가 처리하는 명령어와 1 대 1로 대응되어 있기 때문에, 어셈블리어를 사용하려면 CPU의 내부 동작을 잘 이해해야 한다.

또한 CPU마다 사용하는 명령어 집합이 다르기 때문에 어셈블리어로 작성한 프로그램은 컴퓨터 시스템의 CPU가 달라지면 실행할 수 없다.

어셈블리어는 컴퓨터가 사용하는 기계어에 좀 더 가까운 언어인 반면에, 고급 언어(high level language)는 사람이 사용하는 자연어 쪽에 더 가까운 언어이다.

고급언어는 CPU가 처리하는 명령어와 1 대 1로 대응되는 언어가 아니기 때문에 고급 언어를 이용하면 특정 CPU에 의존적인 프로그램이 아니라 CPU에 대하여 독립적인(independent) 프로그램을 작성할 수 있다.

즉, 프로그래머는 프로그램이 실행될 CPU의 타입에 대하여 신경 쓰지 않고 프로그램을 작성할 수 있는 것이다.

(고급언어에는 C, C++, java, C# 등이 있다.)

고급 언어로 작성된 프로그램이 CPU 안에서 실행되기 위해서는 우선 기계어로 변환되어야 한다.

컴파일러(Compiler)는 고급언어로 작성된 프로그램을 번역해서 기계어로 된 프로그램을 만들어주는 일종의 번역기이다.

즉, 고급 언어로 작성한 프로그램이 컴파일러를 거치고 나면 특정 CPU에서만 실행 가능한 기계어 프로그램으로 바뀌는 것이다.

따라서 고급언어를 사용하려면 해당 언어의 컴파일러가 필요하다.

ex) C언어 -> C 컴파일러

★ 고급 언어로 프로그래밍을 할 때의 장점

· CPU 동작에 대하여 자세히 알 필요가 없다

· 기계어나 어셈블리어를 작성할 때에 비하여 프로그램을 개발하기 쉽다

· 유지 보수가 쉽다

'컴퓨터 공학' 카테고리의 다른 글

임베디드 시스템 (embedded system) 이란  (0) 2024.04.30
컴파일러 (Compiler)  (0) 2024.04.30
콘솔에서의 입력 처리  (0) 2024.04.30
리틀 엔디안, 빅 엔디안  (0) 2024.04.30

시스템을 동작시키는 소프트웨어를 하드웨어에 내장하여 특수한 기능만을 수행하는 컴퓨터 시스템을 말한다.

/

독립 시스템 또는 대규모 시스템의 일부로 전용 기능을 수행하도록 설계된 소프트웨어 포함된 마이크로프로세서 기반 컴퓨터 하드웨어 시스템이다.

정의

An embedded system is a microprocessor- or microcontroller-based system of hardware and software designed to perform dedicated functions within a larger mechanical or electrical system.

임베디드 시스템 애플리케이션은 디지털시계 및 전자레인지부터 하이브리드 차량 및 항공 전자 기기에 이르기까지 다양하다. 제조된 모든 마이크로프로세서의 98%가 임베디드 시스템에 사용된다.

개인용 컴퓨터는 운영체제와 응용프로그램을 하드디스크에 내장하는 반면에,

임베디드 시스템은 운영체제와 응용프로그램을 ROM (Read-Only Memory)이나 플래시 메모리에 저장한다. 이처럼 ROM이나 플래시 메모리에 저장된 소프트웨어를 펌웨어 (Firmware)라고 한다.

임베디드 시스템에서는 개인용 컴퓨터에서 사용되는 CPU와 다른 8비트나 16비트 프로세서가 주로 사용되며, 임베디드용 개발 환경이 따로 있어서 C나 C++ 언어로 임베디드 프로그램을 개발할 수 있다.

gcc나 Visual C++ 등이 대표적인 임베디드용 개발 환경이다.

 

 

참고

https://www.omnisci.com/technical-glossary/embedded-systems

'컴퓨터 공학' 카테고리의 다른 글

기계어, 자연어, 어셈블리어, 고급 언어  (0) 2024.04.30
컴파일러 (Compiler)  (0) 2024.04.30
콘솔에서의 입력 처리  (0) 2024.04.30
리틀 엔디안, 빅 엔디안  (0) 2024.04.30
컴파일러는 소스 코드를 읽고 객체 레벨 코드(object level code)로 변환시키는 기능을 가진 도구이다.
즉, 컴파일러는 소스 파일(source file)을 기계가 이해할 수 있는 객체 파일(object file)로 변환한다

 

 

object code 는 컴퓨터 언어로 된 명령문 또는 명령으로,

일반적으로 기계어 코드 언어(바이너리) 또는 레지스터 전송 언어 (RTL)와 같은 중간 언어이다.

 

 

컴퓨터는 고급 언어인 소스코드는 이해하지 못하고 객체 레벨 코드만 이해할 수 있기 때문에 컴파일 작업이 필요하다.

실수를 입력받는 프로그램

 

 

프로그램 실행 중에 입력 처리를 위해서 키보드를 누르면, 프로그램은 그 즉시 입력을 처리하지 않는다. 콘솔 창에서 키보드로 입력하면, 입력된 값이 곧바로 프로그램으로 전달되는 것이 아니라 임시로 입력 버퍼에 보관된다.

입력버퍼는 입력된 값을 받아오기 위해 사용되는 임시 저장소이다.

키보드로 입력된 값은 일단 입력 버퍼에 보관되었다가 엔터키가 입력되면 비로소 프로그램으로 전달된다.

따라서 엔터키를 입력해야만 실질적으로 입력이 수행된다.

엔디언(Endianness)은 CPU가 다수의 바이트 데이터를 저장하기 위하여 사용하는 방법을 말하며

CPU에 따라 값을 메모리에 저장할 때 어떤 바이트부터 저장할지 설정이 다 다르다.

빅 엔디안(big endian)은 최상위 바이트부터 메모리에 저장하는 방식이고,

리틀 엔디안(little endian)은 최하위 바이트부터 메모리에 저장하는 방식이다.

만약 이 둘에 속하지 않거나 둘을 모두 지원한다면 미들 엔디언(Middle endian)이라고 부르기도 한다.

 

인텔 CPU나 애플 cpu는 리틀 엔디안 방식을 사용하고 모토로라 cpu는 빅 엔디안 방식을 사용한다!

+ Recent posts