brunch

매거진 Sinclair

You can make anything
by writing

C.S.Lewis

by Sinclair Feb 10. 2016

제어문과 반복문

그리고 프로그램은 계속된다 II



switch와 case, default문  


switch문은 조건식에 따라 실행할 문장을 case로 선택할 수 있는 제어문입니다. 기본적인 형태는 다음과 같습니다.  

switch (조건식) {

    case 값1:

        실행문1 ;

    case 값2:

        실행문2 ;

    case 값3:

        실행문3 ;

    …

    case 값n-1:

        실행문n-1 ;

    default : // 조건식이 어떤 case 값도 만족하지 않을 경우

        실행문n ;

} // end switch  



if else문과는 달리 case는 중간에 멈추지 않고 다음 case문으로 계속 진행됩니다. 때문에 조건에 맞는 하나의 case만 실행해야 한다면 break문을 함께 사용해야 합니다. 앞의 성적 처리 문제를 switch case문으로 바꾼다면 다음과 같습니다.  


if( grade > 100 || grade < 0 ) {

    printf("%s" , "성적이 잘못되었습니다") ;

} // end if

else {

    switch (grade / 10) { // grade는 정수형이므로 정수형 몫이 나옵니다.

        case 10:

        case 9 :

            putchar('A') ; break ;

        case 8 :

            putchar('B') ; break ;

        case 7 :

            putchar('C') ; break ;

        case 6 :

            putchar('D') ; break ;

        default :

            putchar('F') ;

    } // end switch case

} // end else   



switch (grade / 10) { // grade는 정수형이므로 정수형 몫이 나옵니다.

    case 10:

    case 9 :

        putchar('A') ; break ;

    case 8 :

        putchar('B') ; break ;

    case 7 :

        putchar('C') ; break ;

    case 6 :

        putchar('D') ; break ;

    case 5 :

    case 4 :

    case 3 :

    case 2 :

    case 1 :

    case 0 :

        putchar('F') ; break ;

    default :

        printf("%s" , "성적이 잘못되었습니다") ;

} // end switch case   



개인적으로 switch문을 별로 좋아하지는 않습니다. case가 늘어 날 때 마다 소스를 고쳐야 하고 프로그램 사이즈도 같이 늘어납니다. 때문에 위의 소스는 아래와 같이 바꿔 사용합니다. 나중에 성적등급이 늘어나거나 줄어도 function()함수를 변경할 필요가 없어집니다.    



static void getDegree(int i) {

    static char degree[] = "FFFFFFDCBAA" ;

    putchar(degree[i]) ;

} // end getDegree()  


int function() {

    // do something~

if( grade > 100 || grade < 0 ) {

    printf("%s" , "성적이 잘못되었습니다.") ;

} // end if

else {

    getDegree(grade/10) ;

} // end else

   // do something~

    return 0 ;

}   




break, continue, return, goto와 label  


break문은 무조건 switch와 가장 가까운 반복문 하나를 빠져 나오는 제어문입니다.  


continue문은 무조건 가장 가까운 반복문의 조건식으로 가는 제어문입니다.  


return문은 무조건 함수를 종료하는 제어문입니다. 반복문이건 제어문이건 관계없이 위치한 그 자리에서 바로 함수를 종료하고 호출한 곳으로 제어를 넘깁니다.


return ; // 함수의 리턴 타입이 void 일 때 사용

return 수식 ; // 함수의 리턴 타입이 존재할 때 사용  


goto문은 무조건 label문으로 가는 제어문입니다. 대부분의 프로그래머나 개발방법론에서 goto는 비효율적이며 분석과 디버깅을 어렵게 만드는 스파게티 식 코드의 주범(?)으로 몰아 절대로 사용하지 말라고(심지어 Java에서는 예약어로 버젓이 존재하면서도 사용할 수 없게 만들어 버렸습니다. 충분히 이해는 되지만) 신신당부를 합니다만, 개인적으로 저는 꼭 필요한 경우라면 goto를 사용해도 좋다고 생각합니다. 여러 개의 반복문을 한꺼번에 빠져 나오기 위해 반복문을 하나씩 빠져나오며 매번 조건을 확인하느니 goto문으로 한번에 나오는 것이 더 낫지 않겠습니까? 버젓이 존재하는 짧고 넓은 길 놔두고 왜 그렇게 힘들게 살아야 합니까? 물론 성경에 좁은 길로 가라고 나오지만 이것 말고도 충분히 힘들고 어려운 세상 아닙니까? 안 그런가요? 하지만 역시 너무 남발 하면 때로는 그 코드를 분석하거나 디버깅해야 하는 다른 사람을 죽일 수 도 있습니다.   



/* 여기부터 시작 */

sinclair: // label이름: 이렇게 사용하는 것을 label문이라고 합니다.

for( i = sizeof matrix / sizeof *matrix ; i > 0 ; ) {

    matrix[--i] = rand() % 45 + 1 ;

    sleep(1) ;

} // end for  


qsort( matrix , sizeof matrix / sizeof *matrix ,

       sizeof *matrix , compare ) ; // 표준 quick정렬 함수


for( i = sizeof matrix / sizeof *matrix - 1 ; i > 0 ; i-- )

{

    for( j = i ; j > 0 ; ) {

        if( matrix[i] == matrix[--j] ) {

            goto sinclair ; /* 처음부터 다시 */

        } // end if

    } // end inner for

} // end outer for   

















#Sinclair #씽클레어 #싱클레어 #씽클레어도씨 #씨언어 #씨프로그래밍  #C언어 #Cprogramming #C_Programming #C #Programming #Clanguage #C_Language

매거진의 이전글 제어문과 반복문
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari