370 likes | 575 Views
구 현 (Coding). - Software Engineering -. 강의 개요. 소 개 프로그래밍 언어 프로그래밍 언어의 역할 및 선택 언어의 구문 제어 구조 자료형 상수 재사용 구조적 프로그래밍 정의 구조적 프로그램 코딩 스타일 원시코드의 문서화. 구 현 (Coding). 목 적 설계 사양을 원시코드로 변환시키는 것. 목적코드. 설계 사양. 코딩. 컴파일 디버깅. 원시코드. 원칙 설계를 철저히 반영시킨다 원시코드는 간단 명료하도록 한다 디버깅이 쉽게
E N D
구 현 (Coding) - Software Engineering -
강의 개요 • 소 개 • 프로그래밍 언어 • 프로그래밍 언어의 역할 및 선택 • 언어의 구문 • 제어 구조 • 자료형 • 상수 • 재사용 • 구조적 프로그래밍 • 정의 • 구조적 프로그램 • 코딩 스타일 • 원시코드의 문서화
구 현(Coding) • 목 적 • 설계 사양을 원시코드로 변환시키는 것 목적코드 설계 사양 코딩 컴파일 디버깅 원시코드 • 원칙 • 설계를 철저히 반영시킨다 • 원시코드는 간단 명료하도록 한다 • 디버깅이 쉽게 • 시험이 용이 • 수정이 간편
Weinberg 의 실험 • 상반되는 원칙을 잘 조화시켜야 함 목표 결과 메모리 출력의 코드의 LOC 개발 이해 이해 기간 메모리 양의 최소화 1 4 4 2 5 출력물의 판독성 극대화 5 1 1-2 5 2-3 원시코드의 이해 극대화 3 2 1-2 3 4 원시코드의 양 최소화 2 5 3 1 2-3 개발기간의 최소화 4 3 5 4 1 1:최적 5: 최악
프로그래밍 언어의 역할 • 컴퓨터를 제어 • 소프트웨어의 구현 및 저장 • 프로그래머 사이의 의사소통 • 논리흐름의 표현 • Documentation • 언어의 기능 vs. 사용자들의 반응 • 소프트웨어의 구조와 알고리즘적인 특성을 크게 좌우
프로그래밍 언어의 발전 • 제 1 세대 언어(저급언어) • 기계어,어셈블리 언어 • 제 2 세대 언어 • FORTRAN,COBOL,ALGOL60,BASIC • 제 3 세대 언어 • 범용:PL/1,Pascal,Modula-2,C,Ada, C++,SIMULA,Smalltalk • 특수:CHILL,RPG,Lisp,Prolog,APL • 제 4 세대 언어(4GL) • non-procedurallanguage • MANTIS,IDEAL,RAMISII,SQL
비주얼 프로그래밍 • VisualBasic의 경우 ① 원하는 윈도우를 그린다 ② 버튼, 텍스트 박스의 속성을(properties)를 설정
비주얼 프로그래밍 ③ 연계된 사건에 대한 코드 작성
프로그래밍 언어의 선택 • 선택 시 고려 사항 • 프로젝트의 상황 • 프로그래밍 언어 자체의 특성
프로젝트의 상황 • 사용자의 요구 • 유지보수 직접 담당 • 프로그래머의 지식 • 숙달된 언어 • 기능의 제한도 파악한 언어 • 완성되었거나 현재 진행되는 프로젝트에 사용되고 있는 언어 • 익숙한 언어 • 두개 이상의 프로젝트가 진행 -> 하나의 언어 • 컴파일러의 가용성과 품질 • 하드웨어 • 적당한 가격 • 목적 코드의 효율성, 품질, 오류 메시지의 분량 • 소프트웨어 개발 도구의 지원 • 에디터, 디버거, 링커, 앞뒤 참조표, 추적기 • 호환성
프로그래밍 언어 자체의 특성 • 표현력과 적합성 • 원하는 작업을 얼마나 효율적으로 충분히 표현할 수 있는가? <예> COBOL : 사무응용분야 C 언어 : 시스템 프로그래밍 Pascal : 프로그래밍 교육(풍부한 자료구조) Modula-2 : 시스템 프로그래밍에 적합 Ada : 실시간 처리 응용 LISP, Prolog : 인공지능 • 단순성, 명확성, 직교성 • 약속어의 개수 <예> COBOL-74: 300여개, COBOL-85: 74개 추가 Pascal: 74개, Modula-2: 64개, Fortran 48개 • 모호성이 없어야 • 직교성: 언어의 기능들을 쉽게 결합할 수 있어야 함
언어의 구문 • 일관적이고 원시코드의 명료성을 증진 <예> ① Pascal의 경우 if TotalSales > BonusLevel then Bonus := Commission + (BonusPercent * TotalSales); if TotalSales > BonusLevel then begin Bonus := Commission + (BonusPercent * TotalSales); BonusMonths := BonusMonths + 1 end ② Ada에서 endIf, endwhile의 사용 if TotalSales > BonusLevel then Bonus := Commission + (BonusPercent * TotalSales) endif if TotalSales > BonusLevel then Bonus := Commission + (BonusPercent * TotalSales); BonusMonths := BonusMonths + 1 endif
언어의 구문 ③ dangling else if conditionA then if concitionB then action1 else action2 if conditionA then if concitionB then action1 endif else action2 endif
제어 구조(Control Structure) • 선택 구조(case구조) • case 선택자의 타입은 가능하면 제한이 없어야 • case 문장의 레이블은 범위를 표시할 수 있어야 • 선택자가 가질 수 있는 모든 값을 열거하도록 강요해서는 안 된다 case Person of when Newborn | Infant => Infant_Seat; when Toddler .. Child => Lap_Belt; when Others => Shoulder_and_Lap_Belt; end case; • 반복 구조 • 반복 횟수를 나타내는 타입이 정수로 제한되어서는 안됨 • 반복 횟수를 나타내는 변수, 초기값을 배정하는 수식, 점증값을 반복되는 구조 안에서 바꿀 수 없다 • 반복 횟수를 나타내는 변수의 정의 범위는 • 반복 문장 안으로 제안하는 것이 바람직
자료형(Data Type) • Strongtypedlanguage • Ada, Modula-2, Pascal • Dynamictypelanguage • Lisp, APL • 단순 자료형 • 실수, 정수, 논리형, 문자형 • 포인터형(Ada, C, Modula-2, Pascal) • 사용자 정의 타입 <예> type Ages=(Infant, Toddler, Preschool, Child, Teenager, Adult); var Person: Ages;
구조 자료형 • 정적 배열 • FORTRAN, Pascal, Modula-2 • 동적 배열 • C 언어, Ada <예> type Puzzle is array (integer range <>, integer range <>) of character; subtype SundayPuzzle is Puzzle(1..50, 1..50); • 구조(structure) <예> type SubscriberType = record Name: array[1..50] of char; IDNumber: 10000..99999; IssuesSent: 0..104; IssuesRemaining: 0..104; SubscriptionType: (New, Renewal, Free, Lifetime) end;
상수(Constant) • const문장 • 단순 자료형(실수, 정수, 문자, 논리형)만 가능(Pascal,Modula-2) • 사용자 정의 타입도 허용(Ada) • #define 사용(C) • 메소드도 가능(C++)
재사용(Ada Package) generic type StackItem is private; package Stack is procedure Push(Element: in StackItem); function Pop return StackItem; . . end Stack; package CharStack is new Stack(character); package IntegerStack is new Stack(integer);
재사용(C++ 클래스) class Employee { private: char* name; positionType position; int salary; ... public: promote(... ); } Employee YoungHee(); 또는 Employee* YoungHee = Employee();
구조적 프로그래밍 • 정의 • 프로그램을 계층적으로 중첩되게 작성하는 규율(formulation) - N. Wirth • 프로그램을 쉽게 이해하고 오류를 줄여 프로그래밍 생산성을 높이려는 목적으로 프로그램 작성에 적용하는 철학 - E. Yourdon • 프로그램의 제어흐름을 선형화시켜 논리구조가 명백하게 하려는 코딩 규율
구조적 프로그래밍 • ProperProgram • 단일입구, 단일 출구 • 모든 노드는 입구에서 도달할 수 있는 경로가 있어야 • 모든 노드는 출구까지 도달할 수 있는 경로가 있어야 • 구조적 프로그램 • 세가지 제어구조(순차, 선택, 반복)로 무조건적 goto에 의한 복잡한 제어흐름을 방지 • 제어구조가 하향식 • stepwise refinement를 이용한 프로그래밍 • StructureTheorem • proper program은 구조적 프로그램으로 변환 가능 • 최신 프로그래밍 언어 • 구조적 언어 문형(if-then, if-then-else, case, while, for, repeat-until 등)
Goto 문의 사용 • 구조적인 제어흐름을 해치지 않는 범위에서 사용 DO50I=1,COUNT . IF(ERROR1)GOTO60 . IF(ERROR2)GOTO70 . 50CONTINUE 60{CodeforError1handling} GOTO80 70{CodeforErrorhandling} 80CONTINUE I=1 forI=1toTableSizedo whileI<=TableSizeandifTable(I)=TargetthengotoFound Table(I)<>Targetdo I=I+1NotFound:{codeforTargetnotfound} ifI>TableSizethenFound:{codeforTargetfound} {codefortargetnotfound} else{codeforTargetfound} (a)구조적 코딩 (b)goto의 사용
코딩 스타일 • 스타일 1:명확하게 작성하라 -너무 똑똑한 체하지 말 것 <잘못된 예> <올바른 예> int i, j; for( i = 0; i < N; i++) { float v[N][N]; for(j = 0; j < N; j++) { . v[i][j] = 0.0; for(i = 1; i <= N; i++) } for( j = 1; j <= N; j++) v[i][j] = 1.0; v[i-1][j-1] = ( i / j )*( j / i ); } • 짧을수록 명확 void FillPowersArray(int base, int *powers) { int i; *powers = base; for (i = 2; i <= 8; i++) *powers+i = *power+i-1 * base; }
코딩 스타일 • 스타일 2: 수식에서 의미하는 바를 간결하고 직접적으로 표현하라 <잘못된 예> <올바른 예> if ( x < y ) { small = x; if ( x < z ) small = x; if ( y < small ) small = y; if ( x > z ) small = z; if ( z < small ) small = z; } if ( x > y ) { if ( y < z ) small = y; if ( y > z ) small = z; } • If ... then ... else에서는 짧은 선택구조를 먼저 <잘못된 예> <올바른 예> if (in_user_code) { if (!in_user_code) revert(); in_user_code = FALSE; else { r2 = r; in_user_code = FALSE; reset_pharlap(); r2 = r; send_sig_segv(); reset_pharlap(); } send_sig_segv(); else revert(); }
코딩 스타일 • 스타일 3: 임시변수의 사용을 피하라 <잘못된 예> <올바른 예> t1 = x1 - ( x2 + x2 ); y=2*(x2-2*x2)+2*(7-x2); t2 = 7 - x2; y = t1 + t1 + t2 + t2; • 스타일 4: 혼돈을 초래하지 않을 변수명을 선택하라 <잘못된 예> NO5S = NO5S + 1; n = k; nn = k * k; nnn = k * k * k; • 혼돈하기 쉬운 글자들 <예> • 1 과 l a1 al • 0 과 O term0 termO • 5 와 S TEXT5 TEXTS • I 와 l Iist list • m과 n의 연속 사용 mnnm mnmn • u와 v의 연속 사용 vuvu uuvu
코딩 스타일 • 스타일 5: 일관성 있는 변수명을 사용하라 • Hungarian notation <예> ptr_to_date_key(포인터), Pi(상수), Person(구조체) • 일관성 있는 이름 <잘못된 예> char buffer[500], mssge[80]; void read_instnance(void), SaveCurrent(void); void get_line(void), write_line(void); int index1, index2; int dirctry, vsble; <올바른 예> char buffer[500], message[80]; void read_instnance(void), save_current(void); void read_line(void), write_line(void); int i, j; int drctry, vsble;
코딩 스타일 • 스타일 6: 문장 그룹이 명확히 구별되도록 { } 와 들여쓰기를 사용한다 <잘못된 예> <올바른 예> for(i= 0; i <N; i++) for ( i = 0; i < N; i++ ) { { k= a[i]; k = a[i]; if (k>100) a[i] =i*3; if ( k > 100 ) else if (j =N) a[i] = i * 3; ... else if ( j = N) } } ... • 스타일 7: 두 가지 중 하나가 선택되는 제어구조는 If-else로 강조한다. <잘못된 예> <올바른 예> if (swctl == '1') goto conti; if(swctl !='1'){ else { divctl+=10; dvictl += 10; swctl='1'; swctl = '1'; } } conti :
코딩 스타일 • 스타일 8: if 다음에 if가 따라오는 구조나 null else는 피할 것 <잘못된 예> if ( qty > 10 ) /* A */ if ( qty > 200 ) /* B */ if ( qty >= 500 ) bill_a += 1.00; /* C */ else bill_a += 0.50; /* C */ else; /* B */ else bill_a = 0.0; /* A */ if ( qty >= 500 ) bill_a += 1.0; else if ( qty > 200 ) bill_a += 0.5; else if ( qty <= 10) bill_a = 0.0; <올바른 예> if ( qty >= 500.0 ) bill+a += 1.0; if ( qty < 500 && qty > 200 ) bill_a += 0.5; if ( qty <= 10 ) bill_a = 0.0;
코딩 스타일 • 스타일 9: 문장의 반복은 최소화한다. <잘못된 예> get_token(); if (tkn == T_END) return; if (tkn == T_START) start_proc(); while (ntokens < T_LIMIT) { process_token(); add_token(); get_token(); if (tkn == T_END) return; if (tkn == T_START) start_proc(); } <올바른 예> for ( ; ; ) { get_token(); if (tkn == T_END) return; if (tkn == T_START) start_proc(); if (T_LIMIT <= ntokens) break; process_token(); add_entry(); }
<잘못된 예> search(board,i,j,movrow,movcol,l) intboard[8][8],i,j,movrow[4],movcol[4],*l; { /*체커 말에는 다음과 같이 코드를 부여한다. 1-백기사, 2-백왕, 3-흑기사, 4-흑왕 말판에서 말이 없는 곳은 0,있는 곳은 말의 코드가 표시된다.movrow, movcol은 가능한 움직임을 나타내기 위한 배열이며 l은 가능한 움직임의 갯수이다. */ intk; if(board[i][j]==0)exit(0); *l=0; k=board[i][j]; if(k==3)gotoback_right; if(i==7)gotoexit_test; if(j==7)gotofor_left; if(board[i+1][j+1]!=0)gotofor_left; moverow[*1]=i+1; movecol[*l]=j+1; *l++; for_left: if(j==0)gotoexit_test; moverow[*l]=i+1; movecol[*l]=j-1; *l++; exit_test: if(k==l)return; back_right: if(i==0)return; if(j==7)gotoback_left; if(board[i-1][j+1]!=0)gotoback_left; moverow[*l]=i-1; movecol[*l]=j+1; *l++; back_left: if(j==0)return; if(board[i-1][j-1]!=0)return; moverow[*l]=i-1; movecol[*l]=j-1; *l++; } 코딩 스타일 • 스타일 8: 모듈화하라. 서브루틴을 사용하라
<올바른 예> search(board,i,j,row,col,l) intboard[8][8],i,j,row[4],col[4],*l; { /* board[I][j] = 0 => 빈 공간 1 => 백기사, 2=> 백왕 3 => 흑기사, 4=> 흑왕 i는 앞이 증가 방향, j는 오른쪽이 증가방향 l은 움직임이 저장되는 row, col의 카운터로 사용됨 */ intk; voidstore(); if(i<0||i>7||j<0||j>7) error("outofboard"); k=board[i][j]; *l=0; if(k<l||k>4)error("misplacedknight"); *l=0; if(k!=3)store(board,i+1,j+1,row,col,l); if(k!=3)store(board,i+1,j-1,row,col,l); if(k!=1)store(board,i-1,j+1,row,col,l); if(k!=1)store(board,i-1,j-1,row,col,l); } voidstore(board,ic,jc,row,col,l) intboard[8][8],ic,jc,row[4],col[4],*l; { if(ic<0||ic>7}}jc<0||jc>7)return; if(board[ic][jc]!=0)return; *l++; row[*l]=ic;col[*l]=jc; } 코딩 스타일
그 밖의 원칙들 • 수식표현 • 명료하게 작성하라 - 효율성을 위하여 명료함을 희생해서는 안된다. • 번거로운 일은 기계가 하로록 만들라. • 괄호를 사용하여 모호성을 제거하라. • 언어의 좋은 기능을 이용하고 불안한 기능의 사용은 피하라 • 제어구조 • 위에서 아래로 읽을 수 있도록 프로그램하라 • 중복구조를 최소화하라. • 맨 처음 작성한 것으로 끝나지 말 것 • 프로그램 • 각 모듈은 분명한 한가지 역할만 수행하도록 하라. • 잘못 작성된 코드는 짜 맞추려하지 하지 말고 다시 작성하라 • 큰 프로그램은 작은 단위로 나누어 따로 작성하고 따로 검사하라.
그 밖의 원칙들 • 입출력 • 자료가 한계 값을 벗어나지 않는지 항상 검사하라. • 입력형식은 사용자가 쉽게 준비할 수 있게 하고 출력형식은 그 모양이 스스로 드러나게 구성하라. • 입출력은 따로 모아서 독립된 서브루틴으로 만들라. • 기 타 • 발견된 오류만 고치지 말 것 - 전체적으로 보고 수정 가능한 모든 오류를 고친다. • 하나 차이에 의한 오류(off-by-one) 를 주의할 것 • 프로그램을 방어적으로 작성하라. • 빠른 프로그램보다 먼저 바른 프로그램을 작성하라. • 빠른 프로그램보다 먼저 명료한 프로그램을 작성하라. • 간결함을 유지하면서 빠른 프로그램을 만들라. • 주석과 코드가 일치하는지 확인하라. • 주석을 달 때 코드를 되풀이해서는 안된다. • 잘못된 코드에는 주석을 달지 말 것 - 다시 작성한다. • 과다하게 주석을 달지 말 것. • 덕지덕지 고쳐서 사용하려고 애쓰지 말 것 - 과감히 버리고 새로 작성한다.
프로그램에 관한 격언들 • The sooner you start to code, the longer the program will take. • If you can't write it down in English, you can't code it. • If the code and the comments disagree, then both are probably wrong. • If you have too many special cases, you are doing it wrong. • Get your data structures correct first, and the rest of the program will write itself. • Don't debug standing up. It cuts your patience in half, and you need all you can muster. • Each new user of a new system uncovers a new class bugs. • Whenever possible, steal code. • Always do the hard part first. If the hard part is impossible, why waste time on the easy part? • If you lie to the computer, it will get you. • One person's constant is another person's variable.
원시코드의 문서화 • 프로그램 헤더 주석 • 프로그램의 제목 • 저작자 • 작성일과 버전번호 • 구조와 설계 • 공유 변수 • 사용되는 화일 • 외부 참조 화일
원시코드의 문서화(예) /********************************************************************************* -EXAMSCORESUMMARYPROGRAM -WRITTENBY:HONG,KILDONG -RELEASEDATE:April1,1994 - -PURPOSE:Thisprogramproducesavarietyofstatisticsona -groupofstudent'sexamscores.Foreachscorethatisentered, -thescoreandarowofstarsrepresentingthemagnituteofthe -scoreisprintedout.Inaddition,thenumberofscores,the -averagescore,thehighestscoreandthelowestscoreare -printedout. - -DESIGN:Theprogramiscomposedofthefollowingmodules: - Mainmodule-TheMain,controllingmodule - ValidateInput-Getsandvalidatestheuser'sinput - ProcessValidScore-Printsscoreandrowofstarsforonescore - UpdateStatistics-Updatesglobalstatistics - PrintSummaryReport-Printssummarystatistics
원시코드의 문서화(예) -MAJORVARIABLES: - SumOfScore(subrangeofinteger,0..2000)- - Thesumofallscoreentered - NumOfStudents(subrangeofinteger,0..100)- - Thetotalnumberofscoreentered - LargestScore(subrangeofinteger,0..20)- - Thelargestscoreinthesetofscores - SmallestScore(subrangeofinteger,0..20)- - Thesmallestscore -FILESUSED: - Input-containsintegerscores,onetoaline - Output-containsaone-linehistogramforeachscore - read,followedonthenextlinebythenumberof - studentsandtheiraveragescore,thenonthenextline - bythetopscore,andconcludingonthenextlinewith - thelowestscore. -EXTERNALREFERENCES:None ******************************************************************************************/