본문 바로가기

Coding-Study/Coding-Study-C

처음부터 써보는 C (2)

이어서 써보도록 하자.

우선, 저번 글(http://dailykul.tistory.com/14)에서 제대로 짚고 넘어가지 않은 부분부터 짚고 넘어갈까 한다.


이 글에서는 모든 구상을 Top-down 방식으로 진행할 것이다. 물론 매우 세부적인 기능들에 대해서는 라이브러리의 기능을 빌려오거나, 작은 것을 먼저 구현하기도 할 수 있으므로, 완전한 Top-down이라고 말할 수 없을지는 모른다. 하지만 되도록이면 더 큰 그림을 먼저 그리려고 할 것이며, 먼저 쓴 글에서 이후에 쓰는 내용을 요구하는 방식을 반복하는 것으로 진행될 것이다.



그러면 다시 코드의 이야기로 돌아와서, 이번에는 Calcode.h와 Eqlib.h를 정리해보았다.

즉, 저번 글에서 어떤 함수들과 타입들이 필요한지 대략적으로 나열해보았다면,

이번 글에서는 구체적으로 어떤 타입 선언을 가지는지, 그리고 어떤 함수 선언을 가지는지를 작성해보았다.


우선, Calcode.h는 다음과 같다. 

  1. #ifndef CALCODE_H_ //#ifndef CALCODE_H_ start
  2. #define CALCODE_H_ //CALCODE_H_ definition
  3.  
  4.  
  5. #define NORMSTR 0x00000000 //Prefix constant for normal condition
  6. #define COMPSTR 0x00010000 //Prefix constant for computational error
  7. #define MATHSTR 0x00020000 //Prefix constant for mathematical error
  8. #define EDITSTR 0x00040000 //Prefix constant for linguistic error
  9.  
  10. typedef enum Errcode_t
  11. {
  12.         NORMAL_STATE = NORMSTR, //NORMAL
  13.  
  14.         OVERFLOW = COMPSTR, //
  15.  
  16.         DIVIDE_ZERO = MATHSTR, NEGATIVE_SQRT,
  17.  
  18.         NOT_NUMBER = EDITSTR, NOT_MATCH_BIG_LEFT, NOT_MATCH_BIG_RIGHT,
  19.         NOT_MATCH_MIDDLE_LEFT, NOT_MATCH_MIDDLE_RIGHT, NOT_MATCH_SMALL_LEFT,
  20.         NOT_MATCH_SMALL_RIGHT,
  21.  
  22.         QUIT = 0xFFFFFFFF
  23. } Errcode_t;
  24.  
  25. typedef struct Err_t
  26. {
  27.         Errcode_t errcode;
  28.         int line_num;
  29.         int char_num;
  30. } Err_t;
  31.  
  32. typedef char Eq_Unit_t;
  33. typedef Eq_Unit_t* Eq_t;
  34. typedef double Num_t;
  35.  
  36. #endif //#ifndef CALCODE_H_ end


우선 에러들을 네 가지로 구분해 놓았다.


1. Normal state

이 경우는 에러가 아니다. 당연하게도.

속하는 경우는 단 한 가지(NORMAL_STATE)밖에 없다.

2. Computational error

컴퓨터 계산 상의 한계로 나오는 에러를 뜻한다.

당장은 OVERFLOW 한 가지 뿐이지만, 더 추가될 수 있다.

3. Mathematical error

수학적으로 계산할 수 없거나 난해한 것들로 인해 나오는 에러를 뜻한다.

0으로 나누기, 그리고 아직 복소수를 제외하고 있기에 제곱근 안에 음수가 있는 경우

등등에 발생하는 에러를 위한 범주이다.

4. Edit error

Typo가 있을 때에 발생할 수 있는 에러들을 뜻한다.

숫자가 아닌 값에 대한 계산(함수는 제외한다), 좌/우 괄호의 비대칭 등이 여기에 포함된다.


이제 각각의 구분을 위해서 상위 16비트를 에러 범주 플래그로 사용하고, 이후의 16비트를 에러의 종류를 구분하는 플래그로 사용하는 열거형을 만들었다.

그리고, Errcode의 특수 플래그로 종료코드(QUIT = 0xFFFFFFFF)을 만들어두었다.


이 열거형은 typedef을 사용해 이름만으로 사용 가능하게 했다.


이제 실제로 사용할 Err_t 형을 만드는데, 저번 글에서 말했듯 이 타입은 에러의 종류, 에러의 위치를 나타낼 것이므로

Errcode_t 형 변수 하나와 int 형 변수 두 개가 필요하므로, 그런 구조체를 선언하였다.


이제 Eq_t 타입을 만들어야 하는데,

수식은 값 하나로 끝나지 않고 어떤 값들의 배열이므로, 어떤 값의 타입을 Eq_Unit_t라고 하면, 그를 가리키는 포인터가 될 것이다.

Eq_Unit_t는 지금은 char형으로, 입력의 편의를 위해 설정하였다. 이후 구현에 문제가 생기면 어떤 구조체로 바뀔 수도 있다.


마지막으로, Num_t 타입은, 수를 표현하는 타입이므로 double의 별칭으로 해 놓았다.



이렇게 Calcode.h를 구성하고 나면, 이제 이 타입들의 선언을 사용할 함수들을 선언할 수 있게된다.


이제 함수들의 선언을 포함하는, Eqlib.h를 보도록 하자.

  1. #ifndef EQLIB_H_ //#ifndef EQLIB_H_ start
  2. #define EQLIB_H_ //EQLIB_H_ definition
  3.  
  4. #include "Calcode.h"
  5.  
  6. Err_t eq_read(Eq_t *to_equation);
  7. Err_t eq_cal(Eq_t equation, Num_t *result);
  8. void eq_print(Eq_t equation, Err_t err, Num_t result);
  9.  
  10. #endif //#ifndef EQLIB_H_ end


비교적 간단하다. Calcode.h를 포함해 기본적인 타입 선언들은 모두 가진 상태에서,

각 함수가 어떻게 작동해야하는지만 생각해보자.


eq_read는 Eq_t 타입에 주소를 할당해야하기 때문에 Eq_t 타입 자체의 값을 바꿔야 하므로 Eq_t의 포인터를 매개변수로 사용한다. 또, Eq_t를 읽어오면서 발생하는 문제들을 반환해야하므로, Err_t 타입을 리턴한다.


eq_cal은 Eq_t 타입의 값을 읽어오기만 하면 되므로 Eq_t 를, 그리고 결과 값을 돌려주어야 하므로 Num_t의 포인터를 매개변수로 사용한다. 또, 계산 과정에서 발생하는 문제들을 반환해야하므로, Err_t 타입을 리턴한다.


eq_print는 Eq_t 타입, Err_t 타입, Num_t 타입의 값만을 읽어오면 되므로 각각을 매개변수로 사용한다. 리턴할 값은 (아직) 필요 없다.



이렇게 코드를 작성하였으면 이제 이들 선언에 해당하는 구현을 만들어야 할 것이다.

즉, (가칭) Eqlib.c를 만들어야 할 것이다.

Eqlib.c의 구현을 대강 생각해보면

eq_read, eq_print는 복잡하지 않으니 넘어간다고 치더라도,

eq_cal은 계산식들의 우선순위를 분석하고 함수를 사용하기 위해서는 적지는 않은 함수들이 필요할 것이고,

이들 함수들을 모두 한 파일에 구현하기보다는 적절하게 쪼개서 구현하는 것이 더 확장하기 좋을 것이다.


따라서 미리 간단한 디렉토리 트리를 구성해 보려고 한다.


구조는 다음과 같다.

Cal

├── Eqlib

└── include

    └── Eqlib


Cal/에는 CalEqulator.c (main함수를 포함한 소스 파일)가 있으며,

Cal/include/에는 Calcode.h가, Cal/include/Eqlib/에는 Eqlib.h가 포함되어있다.


Eqlib.c의 구현은 Cal/Eqlib/에서 이루어질 것이다.


다음 글은 Eqlib.c를 구현하고, 트리 구조를 보다 간편히 빌드하기 위해서 Makefile을 만드는 것으로 하려 한다.

'Coding-Study > Coding-Study-C' 카테고리의 다른 글

처음부터 써 보는 C (1)  (3) 2015.05.07