본문 바로가기

공대남자/프로그래밍

하향식 프로그래밍 설계 기법



사실 프로그래밍에서 가장 중요한 단계는 바로 이 부분이다.

컴퓨터 언어를 공부하는 사람들 중 상당수는 이 단계를 무시하고

어떠한 과제가 주어졌을 때 일단 키보드에 손부터 올리고 본다.

이는 상당히 바람직하지 못한 행동.

프로그래밍 과정 중 코딩의 비중이 20%, 디버깅이 10%라면

나머지 70%는 설계라고 생각한다. (순전히 내 생각임. 태클금지)

어떠한 프로그램을 만들든, 일단 설계가 우선되어야 한다.

그것도 아~주 세분화해서.

design techniques(설계 기법).

이것은 매우 중요하다.

그 중 가장 기초적이고 많이 쓰이는 "하향식 프로그래밍 기법" 을 한번 파헤쳐 보자.




하향식 프로그래밍은 "해결해야 할 문제를 하나의 간단한 문장으로 쓰고 그에 대한 하위 문제를

세분화하여 구현해 나가는 방식" 을 말한다.


단계로 구분하자면,


1. 문제를 한 문장으로 쓴다.

2. 그 문제를 해결하기 위한 세부 작업을 쓴다.

3. 가장 밑바닥까지 세분화한다.



이는 아주 기본적이면서도 중요한 설계 기법이다.

그렇다면 이제 예를 들어서 한번 살펴보자.


이전에 풀어보았던 2차방정식의 해를 구하는 프로그램을 가지고

하향식 프로그래밍으로 다시 한번 짜보자.


먼저 1단계. 문제를 한 문장으로 쓴다.






"2차방정식의 해를 구하고 실근일때, 중근일때, 근이 없을때를 판별하라."






자 이렇게 한 문장으로 썼다.

다음은 이를 세분화하는 단계.

일단은 두 개의 문장으로 나뉠 수 있다.






1) "2차방정식의 해를 구하라."

2) "실근일때, 중근일때, 근이 없을때를 판별하라."







일단 2)번 문장은 잠시 제쳐두고 1)번 문장부터 해결을 해보자.

1)번은 다시 두 개로 나뉘어진다.








(1) "2차방정식의 차수의 계수를 읽어들인다. 각 계수는 a,b,c로 지정한다. (단, a != 0)"

(2) "계산되어 나온 해를 출력한다. 해는 두 개의 변수로 선언한다."

(3) "2차방정식의 근은 근의 공식을 이용해 보자."






첫 두 문장을 main 함수 형태의 알고리즘으로 작성하면 다음과 같다.





int main()
{
   int a,b,c;
   int x1;

   a = read_int();
   a != 0;
   b = read_int();
   c = read_int();

   print_x1;
   print_x2;

   return 0;
}






자 그러면 2차방정식을 구하는 중간과정을 구해보자. (3)번 문장을 다시 세분화 하면





"해가 +,- 두가지 이므로 x1,x2 두 개로 나뉘어 계산을 한다."

"먼저 b^2 부분부터 계산을 한다."

"그 다음 root 부분을 계산한다."

"x1,x2 식에 넣어 근을 구한 다음 출력한다."






네 문장으로 세분화 되었다.

두번째 문장은 제곱승 계산이므로 이에 해당되는 함수인 pow()를 사용해야 한다는 생각이 떠오를 것이다.

pow()를 사용하기 위해서는 math.h 파일을 include 시켜야 하므로 이 또한 코드에 추가시킨다.

코드화 시켜보면





#include <math.h>

//중간 생략

int b2;

b2 = pow(b,2);





세번째 문장은 두번째 문장에서 구한 b2값을 포함시켜서 구해야 한다.

루트 구하는 함수는 sqrt()가 떠오른다.

이 또한 math.h 파일 속에 포함되어 있다.


변수를 rt로 선언하고 코드화 시켜보면





// 일단 다 생략

int rt;

rt = sqrt(b2 - (4*a*c));





그러면 x1,x2 두 근을 구하는 식을 도출해낼 수 있다.





x1 = ((-b) + rt) / (2*a);
x2 = ((-b) - rt) / (2*a);

printf("첫번째 근은 %lf 입니다.\n", x1);
printf("두번째 근은 %lf 입니다.\n", x2);





그러면 처음에 1)번 문장은 끝난 거다.

최종적으로 1)번 코드를 완성해 보면


#include <stdio.h>
#include <math.h>

int main(void)
{
double a=0,b=0,c=0;
double x1=0;
double x2=0;
double b2=0;
double rt=0;

printf("2차방정식 ax^2 + bx + c = 0 (^2는 제곱승 입니다) 의 계수 a,b,c를 차례대로 입력해주세요.\n");
printf("(a는 0이 아니어야 합니다.)\n");

scanf("%lf", &a);
scanf("%lf", &b);
scanf("%lf", &c);
if (a == 0) {       // 이 부분은 따로 설명하기 귀찮아서 그냥 넘어갔다.
printf("잘못 입력하셨습니다.\n");
}
b2 = pow(b,2);
rt = sqrt(b2 - (4*a*c));
x1 = ((-b) + rt) / (2*a);
x2 = ((-b) - rt) / (2*a);
printf("첫번째 근은 %lf 입니다.\n", x1);
printf("두번째 근은 %lf 입니다.\n", x2);

        return 0;
}



자, 그러면 이제 2)번 문장을 세분화시켜 보자.

실근,중근,근이없음 세가지 경우를 생각해서 각각에 해당되는 문자열을 출력해야 되는 것이다.

이를 위해 판별식 b^2-4ac를 사용해 보자.

일단 판별식을 D로 선언하고 코드를 추가하면




D = (b2 - (4*a*c));




로 쓸 수 있다.

이제는 출력을 해야 한다.

세 가지 경우 중 한 가지 경우를 출력하는 것이므로 흔히 쓰는 if문을 사용한다.

코드화 시키면


        if (D>0) {
printf("2차방정식의 실근은 2개로, %lf와 %lf 입니다.\n", x1,x2);
}
else if (D == 0) {
printf("2차방정식의 근이 중근이므로 %lf입니다.\n",x1);
}
else if(D<0) {
printf("2차방정식의 실근이 없습니다.\n");
}



이제 1),2) 두 문장에 대한 코드를 합치면 프로그램이 완성된다.



#include <stdio.h>
#include <math.h>

int main(void)
{
double a=0,b=0,c=0;
double x1=0;
double x2=0;
double b2=0;
double rt=0;
double D=0;

printf("2차방정식 ax^2 + bx + c = 0 (^2는 제곱승 입니다) 의 계수 a,b,c를 차례대로 입력해주세요.\n");
printf("(a는 0이 아니어야 합니다.)\n");

scanf("%lf", &a);
scanf("%lf", &b);
scanf("%lf", &c);
if (a == 0) {
printf("잘못 입력하셨습니다.\n");
}
b2 = pow(b,2);
rt = sqrt(b2 - (4*a*c));
x1 = ((-b) + rt) / (2*a);
x2 = ((-b) - rt) / (2*a);
D = (b2 - (4*a*c));  //판별식


printf("첫번째 근은 %lf 입니다.\n", x1);
printf("두번째 근은 %lf 입니다.\n", x2);


if (D>0) {
printf("2차방정식의 실근은 2개로, %lf와 %lf 입니다.\n", x1,x2);
}
else if (D == 0) {
printf("2차방정식의 근이 중근이므로 %lf입니다.\n",x1);
}
else if(D<0) {
printf("2차방정식의 실근이 없습니다.\n");
}
getch();
return 0;

}





이상으로 하향식 프로그래밍을 적용하여 프로그램을 만들어 보았다.

코드 자체는 논리상 오류가 있을 수도 있다 ㅎㅎㅎ

하지만 설계 과정에서 이러한 방식으로 설계한다면 어떠한 프로그램이라도

좀더 쉽고 논리적으로 명확하게 설계할 수 있을 것이다.

나도 여태껏 코드 짤 땐 항상 키보드에 먼저 손이 갔는데

이를 계기로 좀 더 발전하는 계기가 된 것 같다.



'공대남자 > 프로그래밍' 카테고리의 다른 글

함수는 참 쉽죠잉  (0) 2010.01.11
74LS194  (3) 2009.11.22
쉽지 않은 재귀함수의 이해  (5) 2009.08.11
컴파일러에 따라 다르게 연산되는 증감연산자  (0) 2009.08.05
초간단 계산기 프로그램  (0) 2009.07.29