6장 기본 제어문

제어문은 C 언어 뿐만아니라 다른 프로그래밍 언어에서도 사용하는 문법으로 잘 배워두면 다른 프로그래밍 언어를 배울때도 동일하게 적용하여 빠르게 배울수있다.

6.1 if문

if문은 분기문이라고하며, 조건식을 근거로 구문들의 절차상 흐름을 변경한다.

코드의 흐름이 1가지로 쭉 이어갔지만 지금부터는 여러 갈래의 코드를 동시에 생각해야하고 조건식을 만족하는 경우와 그렇지 못한 경우에 구문 단위 흐름이 어떻게 달라지는지 알아야한다. 또한 연산에 참여하는 변숫값의 변화를 추적할수 있어야한다.

6.1.1 기본 구조

아래 예제 코드가 기본적인 if문의 특징을 살려놓은 코드와 결과이다.

#include <stdio.h>

int main(void){
    int nAge = 0;
    
    printf("나이를 입력 : ");
    scanf("%d", &nAge);

    if(nAge >= 20){
        printf("당신의 나이는 %d 입니다.\n", nAge);
    }

    puts("End");
    return 1; 
}

실행결과
❯ ./welcome
나이를 입력 : 20
당신의 나이는 20 입니다.
End

❯ ./welcome
나이를 입력 : 19
End

if문 안의 조건식이 참인 경우에만 나이를 출력하고 조건식이 거짓이면 나이를 출력하지않는다.

6.1.2 제어문과 스코프

만약 if문에서 조건식을 만족할 때 수행할 구문이 여러 개면 '스코프'로 묶어줘야한다. 아래 예제 코드를 실행하면 20이상 입력해도 if문 스코프 안에 문장이 실행되어 nAge 변수는 20으로 저장되고 if문을 나온후 출력하는 구문에서는 20으로 출력된다.

#include <stdio.h>

int main(void){
    int nAge = 0;
    
    printf("나이를 입력 : ");
    scanf("%d", &nAge);

    if(nAge >= 20){
        printf("당신의 나이는 %d 입니다.\n", nAge);
        nAge = 20;
    }

    printf("당신의 나이는 %d 입니다.\n", nAge);
    return 1; 
}

실행결과
❯ ./welcome
나이를 입력 : 25
당신의 나이는 25 입니다.
당신의 나이는 20 입니다.

06-01 if문을 이용한 최댓값 구하기
사용자로부터 세 정수를 입력받아 그중 가장 큰 수를 출력하는 프로그램을 작성한다.단, 삼항 연산자를 사용하지 말고 반드시 if문을 이용하여 작성하고, 앞서 삼항 조건 연산자에 대해 배울 때 서바이벌 방식으로 설명한 논리를 적용하여 프로그램을 완성한다.

#include <stdio.h>
int main(void){
    
    int nMax;
    int nInput;

    scanf("%d", &nMax);
    
    scanf("%d", &nInput);
    if(nMax < nInput){
        nMax = nInput;
    }
    
    scanf("%d", &nInput);
    if(nMax < nInput){
        nMax = nInput;
    }
    printf("MAX : %d", nMax);
    return 1;

}

실행결과
❯ ./welcome
10
30
-10
MAX : 30%         
06-02 버스요금 계산 프로그램
버스 기본요금을 1,000원이라고 가정하고, 나이가 20세 미만인 영유아, 어린이, 청소년에 대해서 요금을 25% 할인해주고 20세 이상 성인은 할인을 해주지 않기로 한다. 요금 계산 과정에서 자료형에 주의한다. 그리고 요금을 계산하지 않고 '750원'이나 '1000원'을 직접 출력하는 것은 허용되지 않는다.

#include <stdio.h>

int main(void){
    int nFee = 1000;
    int nAge;

    printf("나이를 입력하세요 : ");
    scanf("%d", &nAge);

    if(nAge < 20){
        nFee =  nFee * (1 - 0.25);
    }
    printf("요금은 %d원 입니다.", nFee);
    return 1;


}

실행결과
❯ ./welcome
나이를 입력하세요 : 17
요금은 750원 입니다.%                                                                                          
❯ ./welcome
나이를 입력하세요 : 21
요금은 1000원 입니다.%     

6.2 if else문

if else문은 조건을 만족하는 경우와 그렇지 않은 경우 모두를 처리할 수 있는 제어문 이다.

6.2.1 기본구조

아래 예제 코드를 보면 입력받은 nInput 값이 10보다 작으면 nSelect 가 10이 되고 그렇지 않다면 20이 된다. else문의 오른쪽에는 조건식이 없다.

#include <stdio.h>

int main(void){
    int nInput = 0;
    int nSelect = 0;

    scanf("%d", &nInput);

    if(nInput <= 10)
        nSelect = 10;
    else
        nSelect = 20;

        printf("%d\n", nSelect);
        return 1;
}

실행결과
❯ ./welcome
17
20

6.2.2 중첩된 제어문

제어문 내부에 또 다른 제어문을 기술하여 두 개 이상의 제어문을 한 덩어리로 묶은 것을 말한다.

아래 예제 코든느 if else문 내부에 또 다른 if else문을 중첩한 예제이다. 사용자가 입력한 값을 세 가지 경우로 구별하고 각각 다른 코드를 실행하도록 구성한것이다.

  • 경우 1 : 0미만
  • 경우 2 : 10 이하 0초과
  • 경우 3 : 10 초과
#include <stdio.h>

int main(void){
    int nInput = 0;
    int nSelect = 0;

    scanf("%d", &nInput);
    
    //1차 분류
    if(nInput <= 10){ 
        //2차 분류
        if(nInput < 0)
            nSelect = 0; //경우 1
        else    
            nSelect = 10; //경우 2
    }
    
    else{
        nSelect = 30; //경우 3
    }
    
    printf("%d\n", nSelect); 
    return 1;
}

실행결과
❯ ./welcome
-10
0

이처럼 세분화를 거듭하면 다양한 경우를 다룰 수 있다.

6.2.3 식별자 검색순서(스코프의 중첩)

블록 스코프는 여러 구문을 한 덩어리로 묶어주는 역할과 범위를 제한하는 역할을 한다. 스코프를 벗어난 변수는 사라진다.

6.3 다중 if문

다중 if문은 if else문 여러 개를 연이어 붙인 것처럼 작동하는 제어문이다.
#include <stdio.h>

int main(void){
    int nInput = 0;

    char ch = 'A';
    printf("점수를 입력하세요 : ");
    scanf("%d", &nInput);

    if(nInput >= 90)
        ch = 'A';
    else if (nInput >= 80)
        ch = 'B';
    else if (nInput >= 70)
        ch = 'C';
    else if (nInput >= 60)
        ch = 'D';
    else
        ch = 'F';
    
    printf("학점은 %c 입니다.", ch);
    return 1;
}

실행결과
❯ ./welcome
점수를 입력하세요 : 59
학점은 F 입니다.%     

예제는 마치 계단을 내려오는 것처럼 단계별 비교를 통해 학점을 계산한다. 첫번째로 A 학점의 조건인지 검사하고 조건을 만족하면 A 학점으로 결정하고 전체 다중 if문을 끝낸다.

6.4 switch-case문

switch(변수 혹은 식){
    case 정수1:
    구문;
    break;

    case 정수2:
    구문;
    break;
    .
    .
    .
    
    default:
    구문;
}

switch-case문은 다중 if문이나 중첩된 if문처럼 정보를 '분류'하는 데 사용하는 제어문이다. 기존 if문과 달리 조건식을 단계별 혹은 중첩한 경우를 선택하지 않고 단 한 번의 연산으로 특정한 경우 하나를 선택한다는 것이다.

6.5 goto문

goto문은 특정 위치로 프로그램의 흐름을 '즉시' 변경한다.

goto문은 사용자가 레이블로 명시한 위치면 어디든 이동할수있다. 따라서 아무 제한없이 코드의 흐름을 변경할 수 있다.

이것은 장점처럼 보이지만 매우 심각한 단점이다. 코드의 흐름을 헷갈리게 만들어서 논리적인 결함이 있음에도 해결하기 어려운 상태가 되도록 할 가능성이 높기 때문이다.