조건문은 다른 명령문의 실행을 제어하는 명령문이다. 즉 if, else, case, switch 와 같은 명령문으로 분기된다.

 

if 문

if- then 명령문

  • 일반적인 경우에 대한 코드를 먼저 작성한 다음 특별한 경우를 작성한다
  • 동치에 대해서 정확하게 이동하도록 한다 - >= 대신 > 를 사용하거나 <= 대신 <를 사용하면, 배열에 접근하거나 루프 인데스를 계산할때 하나 차이로 오류(off-by-one)를 만드는 것과 같다.
  • 정상적인 경우를 else가 아니라 if문 다음에 입력한다 - 정상적으로 처리되는 경우를 먼저 작성한다. 이는 결정으로부터의 결과를, 가능한 한 결정을 하는 위치와 가깝게 코드를 작성하는 일반적인 우너칙과 일치한다
  • if 절 다음에는 의미 있는 명령문을 작성한다.

    ex if절이 null인 자바 예제

    if( someTest) ;

    else { // 작업처리

    }

    ex null if절이 변환된 자바예제

    if( !someTest) {작업처리}

  • else절을 고려한다 - 만약 if문이 필요하다면 if-then-else문이 필요 없는지 고려한다. else인 경우를 고려했다는 것을 표시하기 위해 널 절이라도 추가해준다.
  • 정확성을 위해서 else절을 테스트한다
  • if와 else절의 역을 검사한다 - 로직상에 두개의 절 내용이 바뀌는 오류를 확인한다

연속적인 if-then-else 문

case문을 지원하지 않거나 부분적으로만 지원하는 언어에서는 종종 if-then-else테스트를 연속해서 작성하게 될 것이다. 다음은 이것에 대한 지침이다

ex 문자를 분류하기 위해서 일련의 if-then-else를 사용하는 C++예제

if(inputCharacter < SPACE){

 characterType = CharacterType_ControlCharacter;

}

else if {

inputCharacter == '' ||

inputCharacter == ',' ||

inputCharacter == '.' ||

inputCharacter == '!' ||

inputCharacter == '(' ||

inputCharacter == ')'){

chracterType = CharacterType_Punctiation;

}

else if( '0' <= inputCharacter && inputCharacter <= '9') {

characterType = CharacterType_Digit;

}

else if(('a' <= inputCharacter && inputCharacter <= 'z') ||

('A' <= inputCharacter && inputCharacter <= 'Z')){

characterType = CharacterType_Letter;

}

  • 복잡한 테스트를 불린 테스트 호출로 단순화시킨다.

    ex 불린 함수 호출을 사용한 일련의 if-then-else C++예제

    if( IsContorl( inputCharacter))

    {

    chracterType = ChracterType_ControlCharacter;

    }

    else if( IsPunctuation( inputCharacter)){

characterType = CharacterType_Punctuation;

}

else if( IsDigit( inputCharacter)) {

    characterType = CharacterType_Digit;

}

else  if(IsLetter( inputCharacter )){

characterType = CharacterType_Letter;

}

  •  
  • 가장 흔한 경우를 앞에 놓는다 - 가장 흔한 경우를 앞에 놓음으로써, 다른 사람이 일반적인 경우를 찾기 위해서 읽어야 하는 예외적인 상황 처리코드의 양을 최소화할수 있다 그리고 가장 흔한 경우를 찾기 위한 코드 테스트의 수를 최소화하여 효율성을 향상시킨다.

    ex 가장 흔한 경우를 제일 먼저 테스트하는 C++예제

    if(IsLetter( inputCharacter )){ //가장 흔한 테스트가 이제 제일 먼저 수행된다

    characterType = CharacterType_Letter;

    }

    else if( IsPunctuation( inputCharacter)){

    characterType = CharacterType_Punctuation;

    }

    else if( IsDigit( inputCharacter)) {

        characterType = CharacterType_Digit;

    }

    else if( IsContorl( inputCharacter)) //가장 흔하지 않은 테스트가 이제 제일 나중에 실행된다

    {

    chracterType = ChracterType_ControlCharacter;

    }

  • 모든 경우를 다루었는지 확인한다 - 마지막 else 절에는 계획하지 않은 경우를 잡기 위해 오류 메시지나 assertion을 작성하도록 한다.
  • 만약 언어가 지원한다면, if-then-else체인 대신 다른 구조를 사용한다. - case문은 if-then-else체인보다 읽기 쉽고 작성하기 쉽다.

 

CASE문

가장 효율적인 case순서의 선택

  • 알파벳 순으로 또는 숫자순으로 case를 나열한다 - 가독성을 높일수 있다
  • 가장 정상적인 경우를 앞에 놓는다
  • 빈도에 따라서 case를 나열한다

case 문 사용 팁

  • case문이 하는 일을 간단하게 유지한다
  • case문에서 사용하기 위해서 phony 변수를 채우지 않는다 - case문은 쉽게 분류될수 있는 간단한ㅇ 데이터에 대해서 사용되어야 한다. 만약 데이터가 간단하지 않다면, 대신 if-then-else체인을 사용한다. 포니변수(가짜변수)들은 혼란을 야기할수 있기때문에 사용하지 않아야 한다.

ex 포니 case변수를 생성한 자바예제

action = userCommand[0];

switch(action) {

case 'c':

Copy();

break;

case 'd':

DeleteCharacter();

break;

case 'f':

Format();

break;

case 'h':

Help();

break;

//...

default:

HandlingError();

}

이 경우에 case문은 의도와 다르게 동작 가능성이 높다. 사용자가 copy()를 입력할수도 있지만 c로 시작하는 전혀 다른 문장을 입력했을때도 copy()가 실행된다, 올바른 맵핑이 이루어질수 없다. 이런 경우 포니변수 대신에 문자열 비교를 위한 if-then-else체인을 사용하는 것이 좋다

  • 타당한 기본 값을 찾고자 하는 경우에만 dafault절을 사용한다
  • 오류를 검출하기 위해서 default 절을 사용한다
  • C++와 자바에서는 case문의 끝에서 아래로 내려가는 경우를 피한다 - 즉 각 case끝에는 break;를 넣어줘야 한다
  • C++에서는 case문의 끝에서 분명하고 확실하게 아래로 떨어지는것(flow-through)을 확인해야 한다

 

이 글은 스프링노트에서 작성되었습니다.

by 무위자연 2008. 1. 19. 15:54