C 언어(10) - 조건문

C 언어 강의, 조건문

Featured image

🔚 짧게 하는 복습

✅ 1. scanf로 입력받는 법을 알자

✅ 2. 메모리에 값이 저장되는 과정을 알자

✅ 3. 문제해결을 위한 프로그램을 작성하는 데는 입력 -> 연산 -> 출력이 필요하고, 의사 코드를 통해 어떻게 할지 먼저 생각하는 습관을 지니자

혹시 기억이 안 난다면, 다시 돌아가자


벌써 10강이다. 오늘 목표는 다음 강의인 반복문까지기에 3일에 포스팅 12개라는 릴러말즈 뺨치는 작업량을 보여주고 있다.

뭐 이유가 따로 있는 것은 아니고, 취미처럼 천천히 올리면 끝나지 않는다는 것을 이미 2년 전 몸소 경험했었다.

그렇기에 쇠뿔도 단김에 빼라고 다음 주까지 C언어를 끝내고 인도로 인턴십 다녀오는 게 목표다.


현재까지 배운 프로그램의 한계

컴퓨터 공학자들이 언어와 문법을 어느 정도 만든 후, 프로그램의 실행 순서에서 문제를 마주하게 된다.

우리가 배운 것처럼 무조건 위에서 아래로 실행되는데, 이는 현실의 문제와 굉장히 동떨어져 있다.

예를 들어, 현실의 문제는 반복해서 일을 처리해야 할 때도 있고 조건에 맞게 실행했다가 안 했다가를 결정해야 할 때도 있는 법이다.

그래서 처음에는 goto문이라는 문장을 만든다. 이는 원하는 라인의 코드로 넘어가는 문장인데…. 파멸적인 결과를 불렀다.

스파게티 코드의 지옥

이 의사 코드를 보자, 위에서 아래로 갔다가, 아래에서 위로 갔다가 또다시 위로 가고….

대형 프로젝트의 평균 라인 수는 100만 줄, 만약 goto문으로만 짠다면 아무도 이해할 수 없는 코드가 될 것이다.

실제로 이런 복잡한 코드를 스파게티 코드라고 하고, 이렇게 하지 마세요의 정석이다.

제어문

이러한 문제를 해결하기 위해 프로그램에서 진행 순서를 부여하는 제어문이 등장한다.

제어문은 조건문반복문으로 나뉘고, 조건문은 조건에 따라 실행할지, 말지를 정하는 문장이다.

이는 크게 if문과 switch 문으로 나뉜다.

먼저 if 문부터 알아보자.

if 문

if(조건){
    //code1
}

우선 if 문은 기본적으로 위와 같은 구조를 가진다.

이는 조건 부분이 참이면 code1 부분을 실행하고, 아니면 그냥 if로 묶여진 {} 부분(앞으로는 이를 블록이라고 하겠다) 밖으로 그냥 지나가는 것이다.

코드를 직접 실행시켜보자.

오직 character ‘a’가 입력됐을 때만 if 블록이 실행되는 모습이다.

그런데 저기 들어가는 조건은, 관계연산자뿐만 아니라 조건연산자, 논리연산자가 사용될 수도 있다.

주로 사용되는 것은 관계와 논리연산자인데

이런 예제 코드를 보자.

우리가 배운 관계와 논리연산자를 이용해 2가지 조건을 만들어 낸 모습이다.

그런데 이 예제를 실행하다 보면 뭔가 아쉽다는 것이 느껴진다.

키가 180 이상 나이가 13살 이상이면 안내메시지가 출력되는데, 그렇지 않으면 모두 출력이 안 되는 것이다.

else 문

그래서 컴퓨터 공학자들은 이런 경우를 위해, 조건이 참이 아닌 경우 실행되는 else문을 만든다.

if(조건){
    //code1
}
else{
    //code2
}

이렇게 작성하고, 이 경우 조건이 참이면 여전히 code1, 거짓이라면 code2가 실행이 된다.

하지만 여전히 문제가 있다. 키와 나이가 둘 다 모자라지만, 보호자가 동반되었다면 탈 수 있다면?

즉 첫 번째 조건은 안되지만 다른 조건을 만족하면 탈 수 있다면?

else if 문

이런 경우를 위해 만들어진 것은 else if 문 이다.

if(조건1){
    //code1
}
else if(조건2){
    //code2
}
else{
    //code3
}

이렇게 짤 수 있다. 또한, 일반화시켜서 아래처럼 구조를 확장할 수도 있다.

if(조건1){
    //code1
}
else if(조건2){
    //code2
}
else if(조건3){
    //code3
}
else if(조건4){
    //code4
}
...
else{
    //code n
}

그런데 여기서 중요한 점은, 코드의 실행 순서를 정확히 알아야 한다.

if든 else if든, 한 블록에서 조건을 만족하면 그 해당하는 블록만 실행하고 그 밑에 모든 블록은 실행하지 않는다.

반면 조건을 만족하지 않으면, 아래 블록을 순차적으로 확인한다.

모든 조건을 만족하지 않을 때, else 문이 실행된다.

그림으로 그리자면, 이런 모습이다.

첫 번째 그림부터 처음 if 조건이 참 일때, 두 번째 조건이 참일 때, 4번째 조건이 참일 때, 어떠한 조건도 참이 아닐 때이다.

중첩 if 문

if 문의 마지막, 최종 보스. 중첩된 if 문이다.

우리가 실생활에서 마주치는 조건은 생각보다 훨씬 복잡한 경우가 많다.

위 경우를 보자, 논리연산자로 and니 not이니 해도 이것을 일련의 if 문과 else if 문으로 처리하기에는 너무 복잡하다.

그래서 우리는 if 문 안에 if 문들을 넣는 방법을 쓸 수도 있다.

예를 들어, 위의 코드를 수정해서 이렇게 짤 수도 있다.

장점은 논리연산자가 여러 개 중첩될 경우, 중첩된 if 문이 훨씬 알아보기 쉽다는 점이고,

단점은 논리연산자가 2개 정도 중첩된다면, 중첩된 if 문이 훨씬 더 복잡할 수 있다는 점이다.

상황에 맞게 취사 선택하는 것이 중요하다.

switch 문

if, else if, else 문이 중첩되지 않고 조건들의 조건이 모두 정수 혹은 문자형 변수 하나와 그리고 그 변수 하나가 어떤 상수들과 같은지 비교하는 특수한 경우 switch 문이라는 것을 쓸 수 있다. (상수는 우선 변수가 아닌 보통 글자 정도로 이해하고 넘어가자)

예를 들어,

중첩된 if 문도 없고, 문자형 변수 하나를 ‘a’, ‘b’, ‘c’, ‘d’와 같은지 확인하는 이런 경우 말이다.

이런 경우 아래와 같이 switch 문으로 바꿀 수 있다.

규칙은

if(변수 == 상수1){
    //code1
}
else if(변수 == 상수2){
    //code2
}
else if(변수 == 상수3){
    //code3
}
else if(변수 == 상수4){
    //code4
}
...
else{
    //code n
}

인 경우

switch(변수){
    case 상수1 : {
        //code1
        break;
    }
    case 상수2 : {
        //code2
        break;
    }
    case 상수3 : {
        //code3
        break;
    }
    case 상수4 : {
        //code4
        break;
    }
    ...
    default{
        //coden
    }
}

이렇게 각각 매칭할 수 있다.

case는 if 문처럼, switch() 안의 변수가 case 블록의 상수와 같으면 해당 블록 안 코드가 실행된다.

중요한 점은 무조건 case 안에 break을 넣어줘야 한다는 점이다.

switch 문 안의 case는 if 문처럼 자동으로 블록들 밖으로 나가는 기능이 없다.

break 문은 switch 밖으로 나가는 기능을 가진 함수로, 만약 break을 넣지 않으면 끝까지 비교하고 끝까지 실행이 된다.


📖 오늘의 핵심(다 알기 전까지는 넘어가지 말자❗)

✅ 1. if, else if, else, 중첩된 if를 알자

✅ 2. switch 문과 break 문을 이해하자

⚠️ 중첩된 if 문을 써야 하는 상황과 안 쓰는 게 편한 상황은 직접 짜보며 느는 수밖에 없다. 연습을 많이 하자

⚠️ break 문을 까먹지 말자

💣 과제,

  1. 기호(+, -, *, /), 숫자1, 숫자2를 입력받아 계산 값을 출력하는 계산기를 만들어보자(난이도 下) (입력받는 순서는 무조건 기호, 숫자1, 숫자2로 할 것!)

  2. 숫자1, 숫자2, 숫자3, 숫자4를 중복 없이 입력받아 최댓값을 출력해보자. (난이도 中)

  3. 숫자 5개를 중복 없이 입력받아 최댓값, 최솟값을 제외한 합을 구하고 그 3개 숫자의 평균을 구해보자. (난이도 中) (이런 평균을 절사평균이라고 한다.)

🔜 더 공부해보기,

백준(BOJ) 1330번 - 두 수 비교하기

정답 보기
#include <stdio.h>

int main(){
    int a,b;
    scanf("%d %d", &a, &b);
    if (a<b){
        printf ("<");
    }
    else if (a>b){
        printf (">");
    }
    else if (a==b){
        printf ("==");
    }
    return 0;
}

백준(BOJ) 9498번 - 시험 성적

정답 보기
#include<stdio.h>

int main(){
    int num;
    scanf("%d", &num);

    if(num<=100 && num>=90){
        printf("A");
    }
    else if(num>=80 && num<=89){
        printf("B");
    }
    else if(num>=70 && num<=79){
        printf("C");
    }
    else if(num>=60 && num<=69){
        printf("D");
    }
    else{
        printf("F");
    }

    return 0;
}

백준(BOJ) 2753번 - 윤년

정답 보기
#include<stdio.h>

int main(){
    int year;
    scanf("%d", &year);

    if((year%4 == 0 &&year%100 !=0  )|| year%400==0){
        printf("1");
    }
    else{
        printf("0");
    }

    return 0;
}

백준(BOJ) 14681번 - 사분면 고르기

정답 보기
#include <stdio.h>

int main()
{
	int num1, num2;
	scanf("%d", &num1);
	scanf("%d", &num2);

	if (num1 > 0 && num2 > 0) {
		printf("1");
	}
	else if (num1 < 0 && num2 > 0) {
		printf("2");
	}
	else if (num1 < 0 && num2 < 0) {
		printf("3");
	}
	else {
		printf("4");
	}

    return 0;
}

백준(BOJ) 2884번 - 알람 시계

정답 보기
#include<stdio.h>

int main(){
    int hour;
    int minute;

    scanf("%d %d", &hour, &minute);

    int time = hour*60+minute;

    time -= 45;

    if(time<0){
        time += 24*60;
    }

    hour = time/60;
    minute = time%60;

    printf("%d %d", hour, minute);

    return 0;
}

백준(BOJ) 2325번 - 오븐 시계

정답 보기
#include<stdio.h>

int main(){
    int hour;
    int minute;
    int add_time;

    scanf("%d %d %d", &hour, &minute, &add_time);

    int time = hour*60+minute;

    time += add_time;

    if(time>=24*60){
        time -= 24*60;
    }

    hour = time/60;
    minute = time%60;

    printf("%d %d", hour, minute);

    return 0;
}

백준(BOJ) 2480번 - 주사위

정답 보기
#include<stdio.h>

int main(){
    int num1, num2, num3;
    scanf("%d %d %d", &num1, &num2, &num3);

    if(num1 == num2 && num2 == num3){ //3개 다 같다면
        printf("%d", 10000 + num1 * 1000);
    }
    else if(num1 == num2 || num1 == num3){//1과 2, 1과 3이 같다면
        printf("%d", 1000 + num1 * 100);
    }
    else if(num2 == num3){// 2와 3이 같다면
        printf("%d", 1000 + num2 * 100);
    }
    else{
        int temp = (num1 > num2) ? num1 : num2;
        int max = (num3 > temp) ? num3 : temp;
        //조건 연산자를 2번 쓰면 3개의 값 중 최대값을 구할 수 있다.

        printf("%d", max*100);
    }

    return 0;
}