본문 바로가기

컴퓨터/언어,프로그래밍

프로그래밍 단계

1. 프로그래밍 과정

여기서는 프로그래밍 과정을 기초 설계(요구 분석 및 job분배, 스케쥴), 상세 설계 및 구현, 종료 보고 과정을 통해 하나의 프로그래밍을 완성시켜 나가는 과정에 대해 소개하도록 하겠습니다.  이와 같은 개발 공정은 절차식 프로그래밍에서는 적합할 수 있으나 OOP개발 방법과는 다릅니다.  하지만, 이번 장을 통해 여러분들이 설계의 중요성을 깨달을 수 있다면 이후 OOP설계 방법을 익히는 데에도 도움이 될 것이라 확신합니다.  이번 장에서는 이제까지 설명된 기본적인 내용을 토대로 회원 관리 프로그램을 동적 인덱스 배열로 작성할 것이며 다음 장 프로젝트에서는 다양한 형태의 프로그래밍을 예를 소개할 것입니다.  이번 장에서는 전체적인 공정과 각 단계에서 하는 롤에 대한 이해를 해 나가시기 바랍니다.

 

 



1.1  프로그래밍 - 기초설계[타이틀]

이 책에서 얘기하는 기초 설계는 타당성 분석이 끝나 제안한 프로젝트에 대한 요구분석 및 기본적인 설계하는 과정을 얘기합니다.  요구분석 과정에서는 해당 프로젝트에서 관리할 데이터가 무엇인지 구현해야 할 기능은 무엇인지에 대한 결정 및 프로젝트에서 사용할 naming rule등을 정하는 단계가 될 것입니다.  그리고, 기본 설계에서는 관리할 데이터를 어떠한 자료구조로 관리를 할 것이며 구현할 기능들이 전체 프로그램에서 어떠한 요소에서 수행되며 이들을 구현할 내용에 맞게 작업 분배하고 스케쥴을 정하는 단계가 됩니다.  이러한 프로젝트의 앞 단계의 설계가 제대로 되지 않는다면 상세 구현하고 테스트 하는 과정에서 다시 앞단계로 와서 작업을 하게 되어 전체 프로젝트 비용이 커지게 됩니다.  프로젝트에 있어 앞 단계에 많은 비용을 들이는 것은 결국 전체 프로젝트 비용을 줄이는 효과를 보게 되므로 기초 설계는 전체 프로젝트의 성공여부를 결정하는 중요한 부분이라고 할 수 있을 것입니다.  이 책에서 기초 설계는 파워포인터로 작업을 하는 것을 기본으로 하겠습니다.

 

 

프로젝트 기초 설계 문서의 타이틀입니다.  프로젝트 명이나 팀명 및 개발 일시 및 개발자에 대한 부분들이 명시되겠지요. 

 

1.1  프로그래밍 - 기초설계[목차]


프로그래밍 - 기초설계

여기서 부터는 PPT로 작성된 내용을 텍스트로 옮겨서 올립니다.

 - 다음의 각 항목을 전달하는 것을 그 목적으로 하고 있다.

§    프로그래밍 과정 공정에 대한 이해
§    기본적인 C언어 문법을 정리
§    배열과 포인터에 대한 활용
§    동적 메모리 할당에 대한 활용
§

    기본 I/O에 대한 활용

 

개발의 목적이 분명할 수록 좋은 프로젝트가 될 것입니다.  MMP프로젝트를 통해서는 위에 명시된 바처럼 프로그래밍 과정에 대한 이해 및 기본 문법 정리, 배열과 포인터의 활용, 동적 메모리 할당에 관련된 라이브러리 이해, 기본 I/O에 관련된 라이브러리 이해를 하도록 하는데 그 목적을 두고 있습니다.  가장 큰 목적은 프로그래밍 과정에 대한 이해를 하도록 하는데에 있습니다. 

§변수명 : 소문자와 _의 조합, 소문자로 시작
 ex) arr, num, st_num
§함수명 :
     일반화 함수- 소문자로 구성, eh시작
 ex) ehgetnum, ehgetstr
     특수화 함수- 대소문자로 구성,fn으로 시작, 의미가 바뀌는 부분은 대문자
 ex) fnInsert, fnDelete, fnGetData
§태그명: 대문자와 _의 조합, 첫자는 _로 시작
 ex) struct _MEMBER
§타입명: 소문자와 _의 조합, 첫자는 _로 시작
 ex) typedef struct _MEMBER member;
§상수명: 대문자와 _의 조합  

ex) #define MAX_MEMBER 50

 

프로젝트를 시작하기에 앞서 naming rule을 정해 놓아야 팀 작업에서 의사소통에 문제가 없게 됩니다.  여기서는 아주 기본적인 형태의 naming rule만 정하였지만 실제 프로젝트에서는 각 명칭의 길이등 세부적인 사항까지 규칙으로 정하는 경우가 많습니다.  여러분 각자가 naming rule을 정하고 이를 토대로 연습을 해 나간다면 실제 업무를 할 때에도 팀 내 naming rule을 정하고 따르는데 불편함이 없을 것입니다.  좋은 습관이 좋은 엔지니어를 만듭니다 

 

 <UDT>

_member(회원)
멤버명
타입
설명
mnum
int
회원 번호 최소:1 최대:MAX_MEMBER
mname
char [ ]
회원 이름, 배열 크기:MAX_MNAME_LEN+1
flag
_flag
기타정보

 

 

_flag(회원의 기타정보)
멤버명
타입
설명
age
unsigned:8
나이(0살~255살)
sex
unsigned:2
0:미입력, 1:여성 2:남성
btype
unsigned:3
0:미입력,A(1),B(2),O(3),AB(4),기타(5)
reserved
unsgined:18
사용 안함

 

 

실제 프로그램에 헤더파일에 작성하게 될 내용이 될 것입니다.

typedef struct _MEMBER _member;  //회원 데이터 타입

typedef struct _FLAG flag;          //회원의 기타 정보 타입

...중략...

struct _MEMBER                   //회원 데이터 타입 정의

{

   int mnum;                      //회원 번호

   char mname[MAX_MNAME_LEN+1];  //회원 이름

   _flag flag;                      //회원의 기타 정보

};

struct _FLAG                     //회원의 기타 정보

{

    unsigned age:8;              //나이

    unsigned sex:2;              //성별

    unsigned btype:3;            //혈액형

    unsigned reserved:18;        //사용 안함

};

 

 

_md(프로그램 관리화 데이터)
멤버명
타입
설명
cname
char [ ]
조직 이름
배열 크기:MAX_CNAME_LEN+1
base
_member**
관리하는 회원들의 관리 포인터가 있는 base(동적 인덱스 배열)
size
int
최대 관리 회원 수
최소:MIN_MEMBER,
최대:MAX_MEMBER,
기본:DEF_MEMBER
ncnt
int
현재 관리 회원 수
 

 

typedef struct _MD _md;            //프로그램 관리화 데이터 타입

...중략...

struct _MD                         //프로그램 관리화 데이터 타입 정의

{

    char cname[MAX_CNAME_LEN+1];   //프로그램 사용할 조직 이름

    _member **base;                     //관리할 회원들의 관리 포인터들이 있는 위치

    int size;                              //최대 관리 회원 수

    int ncnt;                              //현재 관리 회원 수

};

 

 

enum _BTYPE
상수명
상수값
상수명
상수값
A
1
B
2
O
3
AB
4
ETC
5
MAX_BTYPE
6
enum _SEX
상수명
상수값
상수명
상수값
FEMALE
1
MALE
2
MAX_SEX
3

 

 

 

참고-    #define NO_AVAIL_VALUE 0

 

enum _BTYPE

{

    A=1,

   B,

   O,

   AB,

   ETC,

   MAX_BTYPE

};

 

enum _SEX

{

    FEMALE=1,

    MALE,

    MAX_SEX

};

 

<관리화 상수> 

§#define MAX_MEMBER       1000
     - 최대 관리할 수 있는 회원 수
§#define DEF_MEMBER        10
     - 설절이 잘못되었을 때 기본적으로 관리할 수 있는 회원 수
§#define MIN_MEMBER         10
     - 최소 관리할 수 있는 회원 수
§#define MAX_MNAME_LEN    50
     - 회원의 이름의 최대 수(영문 기준)
§#define MAX_CNMAE_LEN     30
     - 조직의 이름의 최대 수(영문 기준)
§#define FILE_NAME              member.ehd
     - 데이터를 관리할 파일 명
§#define NO_AVAIL_VALUE   0
     - 잘못된 값을 입력 시 대입되는 값

 

 

프로그래밍에 있어 요구 분석단계에서 핵심적인 부분이 자료구조를 선택하는 것입니다.  사실 이와같은 자료구조를 선택하였기 때문에 _md구조체가 정의된 것이라 할 수 있습니다.  자료구조는 관리할 데이터와 구현할 기능에 따라 선택을 해야 합니다.  우리가 특정 자료구조를 구현할 수 있는 능력이야 학습을 통해 얻겠지만 각 프로젝트에서 어떠한 자료구조를 선택할 지는 경험에 의해 나올 수 있는 것입니다.  여러분은 프로젝트를 해 나갈 때 관리할 테이터의 key들의 특징에 따라 적절한 자료구조를 선택할 수 있는 능력을 키워나가시길 바랍니다.  이 책에서는 자료구조에 대한 내용은 깊이 있게 다루지 않고 있습니다.  반드시 자료구조와 알고리즘에 관련된 책을 통해 학습해 나가시길 바랍니다.  전산 엔지니어가 반드시 넘어야 할 산이기 때문입니다.(사실 제일 재미있는 부분이기도 합니다.)

 

  <구현할 기능>

§회원 데이터 삽입 - fnInsert
§회원 데이터 삭제 - fnDelete
§회원 데이터 검색 - fnSearch
§회원 데이터 변경 fnModify
§전체 회원 데이터 보기 - fnListAll
§회원 데이터 저장 - fnSave
§

회원 데이터 로딩 - fnLoad

 

<소프트웨어 구성도> 

 

 

 

 

 

 

<스케쥴> 

 

fnInsert

 

 

 

 

 

 

 

fnDelete

 

 

 

 

 

 

 

fnSearch

 

 

 

 

 

 

 

fnModify

 

 

 

 

 

 

 

fnListAll

 

 

 

 

 

 

 

fnSave

 

 

 

 

 

 

 

fnLoad

 

 

 

 

 

 

 

테스트

 

 

 

 

 

 

 

 

1.2  상세 설계

상세 설계는 기초 설계에서 나눈 작업을 바탕으로 해당 부분에 대한 설계를 하는 단계이다.  여기서 부터는 각 작업군내에서 설계를 하지만 설계의 진행 사항과 프로젝트의 진행을 원활하게 하기 위해서 정해진 시간에 전체 미팅을 주기적으로 해 나가야 한다.  실제 팀 미팅을 하다보면 공통된 작업도 있게 되고 연계되는 작업도 있게 되는데 만약 전체 미팅을 주기적으로 하지 않게 된다면 공통된 작업을 반복해서 할 수도 있을 뿐만 아니라 해당 작업별로 기능 구현이 되어 있다고 하더라도 연동시키는 작업을 하면서 애를 먹을 수 있다. 

 

1.2.1      상세 설계 내용

상세 설계에서는 프로그램의 주 기능들을 스케쥴에 맞추어 설계 및 분임 토의 코딩을 반복하면서 이루어 지게 된다.   이 중 가장 중요한 것은 분임 토의인데 이를 통해 각 기능의 연동할 부분에 대해 의견을 나누게 될 뿐만 아니라 후임 개발자의 부족한 부분을 선임 개발자가 효율적으로 조율해 줌으로써 효과적인 프로젝트가 이루어지게 된다.  SME프로젝트의 각 기능에 대한 설계는 이미 함수 만들기를 하면서 논한바가 있다.  여기에서는 설계된 내용에 맞는 구문으로 변경해 나가는 작업을 해 나가기로 하겠다.

 

입력 기능:

1. 학생 번호를 입력 받는다.

2. 입력받은 번호가 유효한 범위의 번호인지 체크한다.

            유효하다면

            해당 학생이 데이터가 이미 있는지 체크한다.

            있다면

2.1.1.1.1 있다고 통보한다.

            없다면

2.1.1.2.1 해당 학생의 자료를 입력받는다.

            유효하지 않다면

2.2.1 입력한 번호가 유효한 범위를 벗어난다고 통보한다.

삭제 기능:

 

1. 학생 번호를 입력 받는다.

2. 입력받은 번호가 유효한 범위의 번호인지 체크한다.

2.1 유효하다면

2.1.1 해당 학생이 데이터가 이미 있는지 체크한다.

2.1.1.1 있다면

2.1.1.1.1 해당 학생의 자료를 삭제한다.

2.1.12 없다면

2.1.1.2.1 해당 학생의 자료가 없음을 통보한다.

2.2 유효하지 않다면

2.2.1 입력한 번호가 유효한 범위를 벗어난다고 통보한다.

탐색 기능

1. 학생 번호를 입력 받는다.

2. 입력받은 번호가 유효한 범위의 번호인지 체크한다.

2.2 유효하다면

2.1.1 해당 학생이 데이터가 이미 있는지 체크한다.

2.1.1.1 있다면

2.1.1.1.1 해당 학생의 자료를 출력한다.

2.1.12 없다면

2.1.1.2.1 해당 학생의 자료가 없음을 통보한다.

2.2 유효하지 않다면

2.2.1 입력한 번호가 유효한 범위를 벗어난다고 통보한다.

변경 기능

1. 학생 번호를 입력 받는다.

2. 입력받은 번호가 유효한 범위의 번호인지 체크한다.

2.1 유효하다면

2.1.1 해당 학생이 데이터가 이미 있는지 체크한다.

2.1.1.1 있다면

2.1.1.1.1 해당 학생의 자료를 삭제한다.

2.1.1.1.2 해당 학생의 자료를 삽입한다.

2.1.12 없다면

2.1.1.2.1 해당 학생의 자료가 없음을 통보한다.

2.2 유효하지 않다면

2.2.1 입력한 번호가 유효한 범위를 벗어난다고 통보한다.

리스팅 기능

Loop: minimum 학생 번호에서 maximum 학생 번호까지

1. 해당 학생의 데이터가 있는지 체크한다.

조건: 있다면

1.1 해당 학생의 자료를 보여준다.

 

1.2.2      설계된 내용을 코드로 옮기기

위의 설계의 내용을 보면 삽입, 삭제, 탐색, 변경의 기능에서는 공통적으로 학생 번호를 입력받고 이의 유효성 체크 및 해당 번호의 자료가 있는지를 체크하는 로직이 공통적으로 들어가 있다.  이는 분임토의를 해야 하는 또다른 이유로써 해당 기능은 모두 구현할 것이 아니라 한 곳에서만 구현하고 다른 곳에서는 이를 가져다 사용하면 될 것이다. 

 

먼저, 학생 번호를 입력 받는 기능에 대해서 얘기를 해 보기로 하자.  해당 기능에서는 사용자로부터 입력한 번호를 되돌려 받는 것이 주 기능이다.  이는 int fnGetNum();과 같은 형태의 함수로 만들 수 있을 것이다.  또한, SME프로그램에서는 학생 번호가 1번부터 50번까지 한정되어 있다는 것을 고려해 볼 때 해당 범위에 있지 않을 경우에는 0을 반환하고 해당 범위에 있을 경우에만 해당 번호를 반환하도록 만들 수도 있을 것이다.  이러한 것은 분임 토의에서 적절하게 조절이 가능할 것이며 여기서는 int fnGetSNum(int min, int max);와 같은 스타일의 함수 원형을 갖도록 할 것이다.  물론, 여기서는 이미 만들어져 있는 일반화된 함수 int fnInsertSNum(int min, int max);를 사용을 하였다.  이처럼 일반화된 함수군을 하나씩 만들어 나가는 것은 본인 뿐만 아니라 회사의 기술력이 될 수 있는 부분이기 때문에 습관을 들여 나가도록 하자.

 

int num;

 

printf("번호를 입력하세요.[1]-[%d]\n", MAX_STUDENT);

num = fnInsertSNum(1,MAX_STUDENT);

if(num)

{

           /* 구현할 부분 */

}

else

{

           printf("유효한 범위를 벗어났습니다.\n");

}

 

이제 삽입, 삭제, 탐색, 변경에서 번호를 입력받고 유효성을 점검하는 부분은 구현하였다.  각 기능에 따라 /* 구현할 부분 */을 구현하면 간단한 SME프로그램을 기본 기능은 동작할 것이다. 

 

학생 데이터를 삽입하는 기능에서는 해당 학생의 자료가 들어와 있지 않았을 경우에 해당 학생의 데이터를 입력받는 부분이 필요하게 된다.  여기서 해당 학생의 자료가 있는지 확인을 위해서 student구조체에 flag멤버를 두어 삽입시 flag 1 set하고 삭제시 0으로 reset함으로써 확인시에 flag멤버의 값만을 확인하면 된다.  그리고, 해당 학생의 데이터를 입력받는 것은 해당 학생의 데이터를 입력받을 메모리 주소를 매개변수로 주는 함수를 만들어야 할 것이다.

 

if(g_data[num-1].flag)

{

           printf("[%d]의 데이터가 이미 있습니다.\n",num);

}

else

{

printf("[%d]의 데이터를 삽입하세요.\n",num);

           fnGetSData(g_data+(num-1)); 

//배열의 인덱스는 0부터 번호는 1부터이므로 num-1이다.

}

 

  이제 fnGetSData()함수를 작성하면 fnInsert()기능은 일차적으로 완성을 하게 된다.  그런데, 학생 데이터를 입력받는 것은 이미 일반화된 함수를 호출하면 될 것이다.  다만, 마지막에 해당 학생의 flag 1 set하는 것을 잊지 말아야 한다.

 

void fnGetSData(student *p_instu)

{

           printf("이름을 입력하세요.\n");

           fnInsertStr(p_instu->name,MAX_NAME_LEN);

 

           printf("성별을 입력하세요.  여성:[1]  남성:[2]\n");

           p_instu->sex_info = fnInsertSNum(FEMALE,MALE);

 

           printf("국어 점수를 입력하세요.\n");

           p_instu->kscore = fnInsertSNum(0,100);

 

           printf("영어 점수를 입력하세요.\n");

           p_instu->escore = fnInsertSNum(0,100);

 

           printf("수어 점수를 입력하세요.\n");

           p_instu->mscore = fnInsertSNum(0,100);

 

           p_instu->flag = 1;

}

 

삭제의 기능에서는 해당 학생의 자료가 있을 때 flag값을 0으로 체크를 해 주는 것으로써 구현이 종료가 된다.  그 외의 것은 이미 삽입 기능과 동일하다.

 

if(g_data[num-1].flag)

{

           g_data[num-1].flag = 0;

}

else

{

printf("[%d]의 데이터가 없습니다.\n",num);

}

 

탐색 기능에서는 번호, 이름 등 다양한 조건으로 탐색을 가능하게 한다면 좀 더 좋은 프로그램이 될 것이다.  여기서는 프로그래밍 과정을 설명하기 위한 것이기에 단순히 번호에 의한 탐색 기능만을 구현해 보기로 한다.  탐색 기능의 경우도 해당 학생의 데이터를 보여주는 함수 void fnViewData(student *p_instu);를 구현하면 될 것이다.  다른 절차는 삭제 기능과 동일하기 때문이다.

 

if(g_data[num-1].flag)

{

        printf(“[%d]학생의 자료입니다.\n”,num);

           fnViewData(g_data+(num-1));           

}

else

{

           printf("[%d] 데이터가 없습니다.\n",num);

}

 

또한, fnViewData()함수의 경우는 단순히 해당 자료를 보여주는 것이기 때문에 printf함수의 나열에 불과하다.

 

void fnViewData(student *p_instu)

{

           printf("\n\n이름 : [%s]\n",p_instu->name);

           switch(p_instu->sex_info)

           {

           case FEMALE:

                     printf("성별:여성\n");

                     break;

           case MALE:

                     printf("성별:남성\n");

                     break;

           default:

                     printf("성별:알 수 없음\n");

           }

           printf("국어점수 : [%d]\n",p_instu->kscore);

           printf("영어점수 : [%d]\n",p_instu->escore);

           printf("수어점수 : [%d]\n",p_instu->mscore);

}

 

이와 같은 형태로 하나하나 구현해 나가게 되면 하나의 프로그램이 기본적으로 완성이 될 것이다.  물론, 디버깅과 테스트과정을 거쳐야 하겠지만 암튼 설계를 통해 프로그래밍을 하는 것은 그러지 않는 것보다 효율적이라는 것을 느꼈을 것이다.  여러분들은 위의 프로그램을 다시 한번 처음부터 구현해 보길 바란다.(설계 과정을 생략하지 마세요.)

 

이로써 지금까지 학습한 기본적인 문법을 정리하는 프로그래밍을 해 보았다.  여기서는 첫 프로그래밍이기 때문에 거의 모든 소스를 기재하였으나 이후의 프로그래밍 소스는 필요한 부분만을 기재하고 설명하도록 할 것이다.  앞으로의 과정에서는 본인들이 해당 내용에 맞는 프로젝트 주제를 선정해서 작성해 나가길 바란다.


출처 : http://cafe.daum.net/sbehclub/JZbn

'컴퓨터 > 언어,프로그래밍' 카테고리의 다른 글

[C언어] 함수의 흐름  (0) 2009.03.23
[C언어] 함수 - 정의  (0) 2009.03.23
C언어 :: 파일 입출력 - 사용  (0) 2009.03.23
C언어 :: 파일 입출력  (0) 2009.03.23
C언어 :: 동적 메모리 할당 - 사용  (0) 2009.03.23
제주삼다수, 2L,... 오뚜기 진라면 매운... 상하목장 유기농 흰... 남양 프렌치카페 카... 고려인삼유통 홍삼 ... 종근당건강 오메가3... 요이치 카링 유무선...