C언어 3일차-2

정혜창·2024년 12월 15일

독학

목록 보기
8/28
post-thumbnail

if문 활용과 switch ~ case문

if문 중첩

어떤 조건을 검사하기 전에 선행조건이 있다면 if문 안에 if문을 넣어 사용한다.

  • 중첩된 if문(예제)
#include <stdio.h>

int main(void)
{
	int a = 20, b = 10;
    
    if (a > 10) {			// a > 10 이면 밑의 if문 실행, 작거나 같으면 실행x
    
    	if (b >= 0) {		// b >= 0 이면 b에 1 저장하고 printf로 이동
        
        	b = 1;
            
        } else {
        
        	b = -1;			// b < 0 이면 b에 -1 저장하고 printf로 이동
            
        }
    }
    
    printf("a : %d, b : %d\n", a, b);
    
    return 0;
}

if문을 중첩해서 쓰는 이유

  • 선행조건이 있으면 불필요한 조건 검사를 하지 않는다. 예를 들어 위의 예제는 논리곱(&&)을 활용해 같은 의미의 조건문으로 표현할 수 있다.
if ((a > 10) && (b >= 0)) {

	b = 1;
    
}
if ((a > 10) && (b < 0)) {

	b = -1;
    
}

결과는 같지만 이 경우 두 if문의 조건을 모두 검사하므로 실행 효율이 떨어진다.

  • 선행 조건이 없어도 실행 효율을 위해 의도적으로 중첩해 사용할 수 있다.
    이 방법을 분할 정복 기법이라고 하는데 비교 항목이 많은 경우 if문을 중첩해 실행 시간을 줄일 수 있다. 그러나 선행조건이 필요하다고 오해할 수 있고 코드가 읽기 어려워지므로 주의해서 사용해야 한다.

else 결합 문제

문법적으로 if문은 조건에 따라 실행할 문장이 한 문장인 경우 중괄호를 생략가능하다. 그러나 중첩if문에서는 중괄호를 반드시 써야하는 경우가 있다. 실행문으로 기분 if문이 쓰이면 반드시 중괄호가 필요하다.

  • 중첩 if문에서 중괄호가 반드시 필요한 경우(예제)
#include <stdio.h>

int main(void)
{
	int a = 10, b = 20;
    
    if (a < 0){
    
    	if (b > 0){
        
        	printf("ok");
            
        }
        
    } else {
    	
        printf("ok");
        
    }
    
    return 0;
}

컴파일러는 if문이 중첩된 경우 else를 가장 가까운 if와 연결한다. 만약 중괄호 없었다면 else 문이 if (b > 0) 와 짝을 짓게 된다. 이경우 처음 조건문의 a < 0 의 조건이 거짓이고, 기본 if문으로 바뀌므로 결국 아무것도 출력하지 않게 된다.

switch ~ case문

여러 개의 상수 중 조건에 해당하는 하나를 골라 실행하는 것이 switch ~ case문이다.
switch ~ case문을 쓸 때 2가지 규칙

  • 조건식으로 정수식만 이용해야 한다.
  • 기본적으로 case는 break를 포함한다.
    break은 해당 블록을 탈출하는데 사용한다. switch문을 빠져나오는데 사용
  • switch ~ case문의 사용(예제) - 상금을 결정하는 프로그램
#include <stdio.h>

int main(void)
{
	int rank = 2, m = 0;
    
    switch (rank) {			// rank의 값이 얼마인지 확인
    case 1:					// rank가 1이면
    	m = 300;			// m = 300을 수행하고
        break;				// switch문을 벗어남.
    case 2:
    	m = 200;
        break;
    case 3:
    	m = 100;
        break;
    default:				// rank와 일치하는 case의 값이 없으면
    	m = 10;				// m = 10을 수행하고
        break;				// switch문을 벗어남.
    }
    
    printf("m : %d\n", m);
    
    return 0;
}

break 생략

break은 필요에 따라 생략할 수 있다.

switch (rank) {
case 1:
	m += 300;
case 2:
	m += 200;
case 3:
	m += 100;
}

만약 위의 예문에서 break 이없다면 1등의 경우 1,2,3등의 상금을 함께 받고 2등의 경우 2,3등의 상금을 함께 받게 된다. 결국 break이 없다면 블록의 끝까지 모든 문장을 실행한다.
switch ~ case문 대부분은 break을 사용한 다중 선택구문으로 쓰이는 경우가 많고 혹여 제한적으로 break을 생략하는 경우 자세한 설명을 주석으로 남겨두는 것이 좋다.

if ~ else if ~ else문과 switch ~ case문은 동일한 결과를 얻을 수 있을 정도로 비슷하지만 if문 같은 경우는 범위를 검사하는 경우, switch문은 한가지씩 조건을 뽑아내는 경우에 적합하다.

문제. 1

입력한 숫자가 3의 배수면 참, 아니면 거짓으로 나오는 프로그램을 작성하시오.

나의 해답

#include <stdio.h>

int main(void)
{
	int num;
    
    printf("판별하고 싶은 숫자를 입력하세요 : ");
    scanf_s("%d", &num);
    
    switch(num % 3) {
    case 0:
    	printf("참\n");
        break;
    default:
    	printf("거짓\n");
        break;
    }
    
    return 0;
}
        

문제. 2

다음 표에 따라 옷의 사이즈가 결정될 때, 입력하는 나이와 가슴둘레로 자동으로 사이즈를 출력하는 프로그램을 if 문을 사용해 작성하세요.

나의 해답

#include <stdio.h>

int main(void)
{
	int age, chl;
    
    printf("나이를 입력하세요 : ");
    scanf_s("%d", &age);
    printf("가슴둘레를 입력하세요 : ");
    scanf_s("%d", &chl);
        
    if (age < 20) {
    	if (chl < 85) {
        	printf("S\n");
        } else if (chl < 95) {
        	printf("M\n");
        } else {
        	printf("L\n");
        }
    } else {
    	if (chl < 90) {
        	printf("S\n");
        } else if (chl < 100) {
        	printf("M\n");
        } else {
        	printf("L\n");
        }
    }
    
    return 0;
}    

문제. 3

키보드로 수식을 입력하면 계산 결과를 출력하는 프로그램을 작성하세요. 정수 사칙연산만 입력합니다.

#include <stdio.h>

int main(void)
{
	int num_1, num_2;
	int res;
	char op;

	printf("사칙연산 입력(정수) : ");
	scanf_s("%d %c %d", &num_1, &op, sizeof(op), &num_2);

	switch(op) {
	case '+':
		res = num_1 + num_2;
    	break;
	case '-':
    	res = num_1 - num_2;
        break;
    case '*':
    	res = num_1 * num_2;
        break;
    case '/':
    	res = num_1 / num_2;
        break;
    default:
    	printf("사칙연산이 아닙니다. 오류\n");
        break;
    }
    
    printf("%d %c %d = %d\n", num_1, op, num_2, res);
    
    return 0;
}

고찰

  • scanf_s("%d %c %d", num_1, op, num_2) --- X
  • scanf_s("%d %c %d", num_1, op, 1, num_2) --- O

scanf_s 에서 char형이나 char 배열을 입력시킬 때는 크기를 다음 인수에 줘야한다. 더 좋은 방법은 1 보다 sizeof(op) 로 하면 더 좋다.

입력함수 scanf_s 에서 변환문자 %c는 공백이나 개행도 문자로 받아들인다. 이것에 구애받지 않고 오로지 문자만 인식하고 싶다면 변환문자끼리 띄워쓰기하자.

    
profile
Unreal 1기

0개의 댓글