----------------
title : 씹어먹는 C 언어 - <6. 만약에...(if 문)>
cat_title : 6. 만약에... (if 문)
next_page : 12
publish_date : 2009-04-28
path : /C
chapter : 만약에... (조건문)
--------------


이번 강좌에서는

* `if` 문에 대한 이해 - 관계 연산자, 논리 연산자

* `if- else` 문

![씹어먹는 C 언어](/img/ChewingClogo.png)

안녕하세요? 여러분. 이제 저의 강좌도 6강에 이르렀네요. 지난번의 강좌에서 배운 입출력 함수로 여러가지 재미있는 프로그램을 만들었나요? 그러한 프로그램들을 많이 만들 수록 여러분의 실력은 몇 배로 향상된다는 사실을 잊지 마시기 바랍니다. 이번 강좌에는 C 언어에서 매우 중요한 부분인 제어문 - 그 중에서도 조건문이라는 사실을 배우겠습니다.

우리가 자판기에서 음료수를 고를 때 자판기 내부에는 다음과 같은 과정이 수행 됩니다.

![](http://img1.daumcdn.net/thumb/R1920x0/?fname=http%3A%2F%2Fcfile2.uf.tistory.com%2Fimage%2F122CFA1649FDB5F0B88E78)

돈을 넣는다. 지폐인가? 맞다면 액수가 충분한가? 아니면 더 받는다. 이렇게 맞다 아니다 로 갈리게 됩니다. 이러한 것을 조건문 이라고 합니다. 즉 항상 실행되는 것이 아니라 특정한 조건이 맞는 경우에만 실행되는 것이지요

그런데, 위 부분에서 우리가 여태 까지 보지 못했던 특징이 있습니다. 여태까지 우리는 모든 문장들이 순차적으로 실행되어 왔습니다. 예를들어,

```cpp-formatted
//.....
printf("안녕\n");
printf("내 이름은 Psi 야 \n");
printf("너의 이름은 뭐니?\n");
//....

```

와 같은 문장에서 처음에 **안녕** 이 출력되고 그 다음에 **내 이름은 Psi 야**, 그리고 마지막으로 **너의 이름은 뭐니?** 가 출력이 됩니다. 안녕이 출력이 되지 않거나 너의 이름은 뭐니? 가 출력되지 않는 일은 없죠.

뿐만 아니라, 내 이름은 Psi 야가 안녕 보다 먼저 출력되는 경우도 없습니다. 단지 어떠한 조건에서도 안녕, 내 이름은 Psi 야, 너의 이름은 뭐니? 가 차례대로 출력되는 것이지요.

하지만, 위의 그림을 봅시다. **지폐 인가?** 부분을 보면 만약 Yes 라면 **액수는 충분한가?** 를 실행하고 No 라면 **동전 인가?** 를 실행하게 끔 되어 있습니다. 다시말해 어떠한 경우를 만족한다면 이것을 실행하고, 또 다른 경우라면 이 것을 실행하는 꼴이지요. 이런 것을 '조건문' 이라 합니다. 어떠한 조건에 따라 실행되는 것이 달라지는 것이지요.




### if 문 시작하기

  아래 예제를 봅시다.

```cpp-formatted
/* if 문 이란? */
#include <stdio.h>
int main() {
  int i;
  printf("입력하고 싶은 숫자를 입력하세요! : ");
  scanf("%d", &i);

  if (i == 7) {
    printf("당신은 행운의 숫자 7 을 입력했습니다");
  }

  return 0;
}
```


위 예제를 성공적으로 컴파일 한 후, 7 을 입력하였으면

```exec
입력하고 싶은 숫자를 입력하세요! : 7
당신은 행운의 숫자 7 을 입력했습니다
```

와 같이 나오게 됩니다. 그런데, 7 이 아닌 다른 수를 입력하였을 때 에는,

```exec
입력하고 싶은 숫자를 입력하세요! : 1
```

 처럼 나오게 됩니다. 일단, 위 소스 코드에는 우리가 여태까지 보지 못했던 것이 있으니 찬찬히 뜯어 보도록 합시다.

```cpp-formatted
if (i == 7) {
  printf("당신은 행운의 숫자 7 을 입력했습니다");
}
```

이는위 소스코드에서 가장 핵심적인 부분입니다. 영어에서 흔히 말할 때 어떨 때, if 라는 단어를 쓰나요. 예를 들어서, *If you are smart enough, please learn C language* (만약 당신이 충분히 똑똑하다면, C 언어를 배워라!) 라는 문장을 보았을 때 **If** 라는 단어는 무슨 역할을 하나요? 아마 영어를 조금이나마 배운 사람들이라면, **if** 는 '만약 `~` ' 이라는 의미를 가진 것임을 바로 알 수 있습니다.

C 언어에서도 마찬가지 입니다. `if` 는 가정을 나타냅니다. 여기서는 무엇을 가정 하였을까요? 바로 `if` 문 안에 있는 `i == 7` 이 그 가정을 나타냅니다. 즉, *만약 `i` 의 값이 7 이라면* 이라는 뜻이지요.

`if` 문은 언제나 괄호 안의 조건이 참 이라면 중괄호 속의 내용을 실행하게 되고, 아니면 중괄호 속의 내용을 실행하지 않고 지나치죠.

따라서, 만약 `i` 의 값이 7 이라면,

```cpp-formatted
printf("당신은 행운의 숫자 7 을 입력했습니다");
```

를 실행 한 후 중괄호 밖으로 빠져 나갑니다. 그 후 다시 아래로 순차적으로 실행하게 되죠. 즉, 마지막으로 `return 0;` 가 실행됩니다.

그런데, `i` 의 값이 7 이 아니라면, `if` 문의 중괄호 속의 내용은 실행되지 않고 지나쳐 버립니다. 왜냐하면 `if` 문 에서 `i == 7` 이 '거짓' 이 되기 때문이죠. 따라서 그냥 `return 0` 만 실행이 됩니다.

참고적으로 `==` 와 같이 어떠한 두 값 사이의 관계를 나타내 주는 연산자를 **관계 연산자** 라고 부릅니다. 이 때, 관계 연산자의 좌측에 있는 부분을 좌변, 우측에 있는 부분을 우변이라 합니다. (즉, `3 == 2` 와 같은 경우 3 은 좌변, 2 는 우변 이라 부릅니다)

또한, 알아야 될 또 한가지 중요한 것은, 사실 관계 연산자는 어떠한 관계를 연산 한 후에, 참 이면 1 을, 거짓이면 0 을 나타내게 됩니다.

다시 말해, `if` 문은 참, 거짓에 따라서 중괄호 속의 내용을 실행 하느냐, 하지 않느냐 결정하는 것 처럼 보이지만 실제로는, **`if` 문 속의 조건이 0 인가 (거짓), 0 이 아닌가 (참) 에 따라서 실행의 유무를 판별하게 되죠**

따라서, `if (0)` 이라 한다면 그 중괄호 속의 내용은 절대로 실행되지 않고, `if(1)` 이라 한다면 그 중괄호 속의 내용은 `100%` 실행되게 됩니다.

```cpp-formatted
/* 나눗셈 예제 */
#include <stdio.h>
int main() {
  double i, j;
  printf("나누고 싶은 두 정수를 입력하세요 : ");
  scanf("%lf %lf", &i, &j);

  printf("%f 를 %f 로 나눈 결과는 : %f \n", i, j, i / j);

  return 0;
}
```

성공적으로 컴파일 후 10 과 3 을 입력하였다면 아래와 같이 나오게 됩니다

```exec
나누고 싶은 두 정수를 입력하세요 : 10
3
10.000000 를 3.000000 로 나눈 결과는 : 3.333333 
```

와우! 성공적으로 되었습니다. 그런데 위에서 나온 소스 코드는 우리가 여태까지 바왔던 코드와 다를 바가 없습니다. 여태까지 배운 기능들만 이용해서 만든 것이지요. 하지만 바로 이 부분에서 문제가 대두됩니다.

컴파일한 프로그램을 다시 실행시켜 1 과 0 을 차례대로 입력해 보세요. 즉, 1 을 0 으로 나누어 보세요.

```exec
나누고 싶은 두 정수를 입력하세요 : 1
0
1.000000 를 0.000000 로 나눈 결과는 : inf 
```

위에서 보시는 것과 같이 나눈 결과가 `inf` 이라는 이상한 결과를 내뿜었습니다. 왜 일까요? 왜냐하면 수학에서, (즉 컴퓨터 에서) 어떠한 수를 0 으로 나누는 것은 금지되어 있기 때문이죠. 위 `i` 와 `j` 변수가 `double` 로 선언되어 있어서 망정이지 `i,j` 변수를 `int` 형으로 선언하였다면 프로그램은 에러를 내뿜고 종료 됩니다.

이 문제를 대수롭지 않게 여긴다면 큰 문제입니다. 예를들어서 여러분이 엑셀로 열심히 작업을 하였는데 실수로 어떤 수를 0 으로 나누는 작업을 하였더니 힘들게 작업한 엑셀이 종료되 버려 파일이 날아가 버리면 여러분은 다시는 엑셀을 쓰지 않을 것 입니다. 따라서, 우리는 나누는 수 (제수) 가 0 이 아닌지 확인할 필요성이 있습니다. 즉, 제수가 0 이면 나누지 않고 0 이 아니면 나누는 것이지요.

따라서 위 프로그램을 아래와 같이 수정합시다.

```cpp-formatted
#include <stdio.h>
int main() {
  double i, j;
  printf("나누고 싶은 두 정수를 입력하세요 : ");
  scanf("%lf %lf", &i, &j);

  if (j == 0) {
    printf("0 으로 나눌 수 없습니다. \n");
    return 0;
  }
  printf("%f 를 %f 로 나눈 결과는 : %f \n", i, j, i / j);

  return 0;
}
```

만약 1 을 0 으로 나누었다면

```exec
나누고 싶은 두 정수를 입력하세요 : 1 
0
0 으로 나눌 수 없습니다. 
```

그리고 다시 10 을 3 으로 나누어 보면

```exec
나누고 싶은 두 정수를 입력하세요 : 10 
3
10.000000 를 3.000000 로 나눈 결과는 : 3.333333 
```

로 위와 같이 정상적으로 나타납니다. 그럼 위 소스코드를 뜯어 보기로 합시다.

```cpp-formatted
{
  printf("0 으로 나눌 수 없습니다. \n");
  return 0;
}
```

만약 `j` 의 값이 0 이라면 중괄호 속의 내용이 실행되며, *0 으로 나눌 수 없습니다* 가 표시되고 프로그램이 종료(`return 0`) 됩니다.

반면에, `j` 의 값이 0 이 아니라면 중괄호 속의 내용이 실행되지 않습니다. 즉, 아래의 내용이 실행되게 됩니다.

```cpp-formatted
printf("%f 를 %f 로 나눈 결과는 : %f \n", i, j, i / j);

return 0;
```

이렇듯, `if` 문은 여러 조건에 따른 처리를 위해 사용합니다. 먼저 나왔던 예제는 `i` 의 값이 7 일 때의 처리를 위해 `if` 문을 사용하였고 위의 예제는 `j` 의 값이 0 일 때의 처리를 위해 사용하였습니다.

```cpp-formatted
/* 합격? 불합격? */
#include <stdio.h>
int main() {
  int score;

  printf("당신의 수학점수를 입력하세요! : ");
  scanf("%d", &score);

  if (score >= 90) {
    printf("당신은 합격입니다! \n");
  }

  if (score < 90) {
    printf("당신은 불합격 입니다! \n");
  }

  return 0;
}
```

위 소스를 성공적으로 컴파일하였다면 다음과 같이 나옵니다.
만약 당신의 수학점수로 91 점을 입력하였다면,

```exec
당신의 수학점수를 입력하세요! : 91
당신은 합격입니다! 
```

만약 당신의 수학 점수로 80 점을 입력하였다면

```exec
당신의 수학점수를 입력하세요! : 80
당신은 불합격 입니다! 
```

와 같이 나타납니다.

```cpp-formatted
if (score >= 90) {
  printf("당신은 합격입니다! \n");
}

if (score < 90) {
  printf("당신은 불합격 입니다! \n");
}
```

위 소스의 핵심이라 할 수 있는 부분은 위 두 부분입니다.일단, `if(score >= 90)` 이라는 부분부터 살펴 봅시다. 이미 짐작은 했겠지만 `>=` 은 *~ 이상*, 즉 *~ 보다 크거나 같다* 를 의미합니다. 따라서, `score` 의 값이 90 보다 '크거나 같으면' `if` 문 안의 내용이 참 (true) 이 되어 중괄호 속의 내용이 실행됩니다.

따라서, 처음에 우리가 91 점을 입력하였을 때 `score >= 90` 이 참이 되어서 

```cpp-formatted
printf("당신은 합격 입니다! \n");
```

가 실행되었습니다. 그런데 여기서 주의해야 할 점은 `score => 90` 이라고 하면 안된다는 것 입니다. 이렇게 쓰면 컴파일러는 인식을 하지 못합니다.

이 부분에서 헷갈리는 사람들은 '크거나 같다' 라는 말 그대로 옮겨 적었다고 생각하세요. `>=` 는 크거나 (>) 같다 (=) 를 합친 것이다!

마찬가지로, 아래 `score < 90` 도 보자면 `score` 가 90 미만일 때 참이다 라는 사실을 나타낸 것임을 알 수 있습니다.

```cpp
/* 크기 비교하기 */
#include <stdio.h>
int main() {
  int i, j;

  printf("크기를 비교할 두 수를 입력해 주세요 : ");
  scanf("%d %d", &i, &j);

  if (i > j)  // i 가 j 보다 크면
  {
    printf("%d 는 %d 보다 큽니다 \n", i, j);
  }

  if (i < j)  // i 가 j 보다 작으면
  {
    printf("%d 는 %d 보다 작습니다 \n", i, j);
  }

  if (i >= j)  // i 가 j 보다 크거나 같으면
  {
    printf("%d 는 %d 보다 크거나 같습니다 \n", i, j);
  }
  
  if (i <= j)  // i 가 j 보다 작거나 같으면
  {
    printf("%d 는 %d 보다 작거나 같습니다 \n", i, j);
  }

  if (i == j)  // i 와 j 가 같으면
  {
    printf("%d 는 %d 와(과) 같습니다 \n", i, j);
  }

  if (i != j)  // i 와 j 가 다르면
  {
    printf("%d 는 %d 와(과) 다릅니다 \n", i, j);
  }

  return 0;
}
```

위 내용을 성공적으로 컴파일 후, 10 과 4 를 입력하였다면

```exec
크기를 비교할 두 수를 입력해 주세요 : 10 4
10 는 4 보다 큽니다 
10 는 4 보다 크거나 같습니다 
10 는 4 와(과) 다릅니다 
```

와 같이 나타나게 됩니다.

이번 예제에서는 소스의 길이가 약간 깁니다. 하지만 따지고 보면 상당히 간단한 구조로 되어 있음을 알 수 있습니다. 일단 위의 예제에 관계 연산자 들의 역할에 대해 알아봅시다.

1. `>=`  : 좌변이 우변보다 같거나 크면 참이 됩니다. (`6 >= 3` : 참, `6 >= 6` : 참, `6 >= 8` : 거짓)
2. `>` : 좌변이 우변보다 크면 참이 됩니다. (`6 > 3` : 참, `6 > 6` : 거짓, `6 > 8` : 거짓)
3. `<=` : 좌변이 우변보다 작거나 같으면 참이 됩니다. (`6 <= 3` : 거짓, `6 <= 6` : 참, `6 <= 8` : 참)
4. `<` : 좌변이 우변보다 작으면 참이 됩니다.(`6 < 3` : 거짓, `6 < 6` : 거짓, `6 < 8` : 참)
5. `==` : 좌변과 우변이 같으면 참이 됩니다.(`6 == 3` : 거짓, `6 == 6` : 참, `6 == 8` : 거짓)
6. `!=` : 좌변과 우변이 다르면 참이 됩니다. (`6 != 3` : 참, `6 != 6` : 거짓, `6 != 8` : 참)

따라서, 위 관계연산자에 따라 위 프로그램이 실행이 됩니다. 한 번 여러가지 숫자를 집어 넣으면서 확인해 보세요.

마지막으로 `if` 문의 구조에 대해서 간단히 정리해 보자면

```cpp
if (/* 조건 */)
{
/* 명령 */
}
```

와 같이 됩니다. 잊지 마세요!

### if - else 문 시작하기

```cpp-formatted
#include <stdio.h>
int main() {
  int num;

  printf("아무 숫자나 입력해 보세요 : ");
  scanf("%d", &num);

  if (num == 7) {
    printf("행운의 숫자 7 이군요!\n");
  } else {
    printf("그냥 보통 숫자인 %d 를 입력했군요\n", num);
  }
  return 0;
}
```

만약 성공적으로 컴파일 하였다면 7 을 입력했을 때,

```exec
아무 숫자나 입력해 보세요 : 7
행운의 숫자 7 이군요!
```

그리고, 그 외 7 이 아닌 다른 숫자를 입력하였을 때 에는,

```exec
아무 숫자나 입력해 보세요 : 100
그냥 보통 숫자인 100 를 입력했군요
```

와 같이 나오게 됩니다. 자, 이제 위 소스를 뜯어 봅시다.

```cpp-formatted
if (num == 7) {
  printf("행운의 숫자 7 이군요!\n");
}
```

여태 까지 보왔듯이, 이 부분은 그냥 평범한 `if` 문이군요. 하지만 그 다음 부분에 심상치 않은 것이 등장합니다.

```cpp-formatted
else {
  printf("그냥 보통 숫자인 %d 를 입력했군요\n", num);
}
```

이번에는 여태까지 배우지 않은 것인 `else` 라는 것이 등장합니다. 영어를 잘 하시는 분들은 지레 짐작하시고 있었겠지만 `else` 는 '그 외의~ , 그 밖의~' 의 뜻으로 사용되는 단어입니다. 

그렇다면 여기서도 그러한 의미를 나타내는 것인가요?

맞습니다. `else` 는 바로 '앞선 `if` 문이 조건을 만족하지 않을 때' 를 나타냅니다. 즉, 앞선 `if` 문이 조건을 만족 안할 때 해야 할 명령을 바로 `else` 문에 써 주는 것이지요. 다시 말해, `else` 문은 떨거지(?) 들을 처리하는 부분입니다.

위의 경우에서도 만약 `num` 의 값이 7 이 아니였다면 `if` 문을 만족 안하게 되는 것입니다. 그러면 자연스럽게 `else` 로 넘어와서 "그냥 보통 숫자인 ... 를 입력했군요" 를 출력하게 되는 것이지요. 하지만, `num` 의 값이 7 이 였다면 `if` 문을 만족하는 것이기 때문에 `else` 는 거들떠 보지도 않고 넘어가게 됩니다.

```cpp-formatted
/* if - else 죽음의 숫자? */
#include <stdio.h>
int main() {
  int num;

  printf("아무 숫자나 입력해 보세요 : ");
  scanf("%d", &num);

  if (num == 7) {
    printf("행운의 숫자 7 이군요!\n");
  } else {
    if (num == 4) {
      printf("죽음의 숫자 4 인가요 ;;; \n");
    } else {
      printf("그냥 평범한 숫자 %d \n", num);
    }
  }
  return 0;
}
```

이번에 성공적으로 컴파일 한 후, 숫자들을 입력해 보면 비슷한 결과가 나오지만 4 를 입력했을 경우 "죽음의 숫자 4 인가요 ;;; " 가 나오게 됩니다.

```exec
아무 숫자나 입력해 보세요 : 4
죽음의 숫자 4 인가요 ;;; 
```

자, 이제 소스를 뜯어 보기로 합시다.

```cpp-formatted
else {
  if (num == 4) {
    printf("죽음의 숫자 4 인가요 ;;; \n");
  } else {
    printf("그냥 평범한 숫자 %d \n", num);
  }
}
```

앞 `if (num == 7)` 부분은 이미 설명 했으니 생략하기로 하고, `else` 문의 구조만 뜯어 보기로 합시다. 만약 `num` 의 값이 4 였다고 합시다. 그렇다면, 처음에 만나는 `if` 문에서 `num == 7` 이 거짓이 되므로 `else` 로 넘어가게 됩니다.

그런데, `else` 의 명령을 실행하려고 하는데 보니, 또 `if` 문이 있네요. 이번에는 `if (num == 4)` 가 나타납니다. 하지만 아까와는 달리 `num == 4` 가 참이므로 그 `if` 문의 중괄호 속의 명령, 즉 "죽음의 숫자 4 인가요 ;;;" 가 출력되게 됩니다.

그리고, 앞 예제에서 설명했듯이 `if(num == 4)` 아래의 `else` 는 무시 하게 되고, 끝나게 되는 것이지요.

그렇다면 이제 아이디어를 확장해서 `num` 이 1 부터 10 일 때 까지 특별한 설명을 달기로 합시다. 그러면 아래와 같이 프로그램을 짜야 되겠죠.

```cpp-formatted
/* 쓰레기 코드 */
#include <stdio.h>
int main() {
  int num;

  printf("아무 숫자나 입력해 보세요 : ");
  scanf("%d", &num);

  if (num == 7) {
    printf("행운의 숫자 7 이군요!\n");
  } else {
    if (num == 4) {
      printf("죽음의 숫자 4 인가요 ;;; \n");
    } else {
      if (num == 1) {
        printf("첫 번째 숫자!! \n");
      } else {
        if (num == 2) {
          printf("이 숫자는 바로 두번째 숫자 \n");
        } else {
          ......(생략)......
        }
      }
    }
  }
  return 0;
}
```

정말 믿도 끝도 없이 길어져서 나중에는 중괄호가 너무 많아 헷갈리기도 하고, 보기도 불편하게 됩니다. 하지만, C 언어는 위대한지라, 이 문제를 간단히 해결하였습니다.

```cpp-formatted
/* 새로쓰는 죽음의 숫자 예제 */
#include <stdio.h>
int main() {
  int num;

  printf("아무 숫자나 입력해 보세요 : ");
  scanf("%d", &num);

  if (num == 7) {
    printf("행운의 숫자 7 이군요!\n");
  } else if (num == 4) {
    printf("죽음의 숫자 4 인가요 ;;; \n");
  } else {
    printf("그냥 평범한 숫자 %d \n", num);
  }
  return 0;
}
```

위 코드를 실행해 보면 앞선 예제와 똑같이 작동합니다. 하지만 코드도 훨씬 보기 편해 졌고 난잡하던 중괄호도 어느 정도 정리가 된 것 같군요. 그렇다면 정말 하는 일이 똑같을 까요? 네, 똑같습니다. 왜냐하면

```cpp
    if(/* 조건 1 */)
    {
        // 명령 1;
    }
    else
    {
        if(/* 조건 2 */)
        {
            // 명령 2;
        }
        else
        {
            if (/* 조건 3 */){
            // 명령 3;
            }
            else
            {
                // ....
            }
        }
    }
```

위와 같은 코드를 단지 아래 처럼 '간단히' 표현한 것이기 때문이죠.

```cpp
    if(/* 조건 1 */)
    {
        // 명령 1;
    }
    else if(/* 조건 2 */)
    {
       // 명령 2;
    }
    else if(/* 조건 3 */)
   {
       //명령 3;
   }
   ....
  else {
        // 명령 ;
    }
```

단지, 보기 편하게 하기 위해 '간략하게' 줄인 꼴과 같다는 것입니다. 마치 `a = a + 10` 을 `a+= 10` 으로 바꾼 것 처럼 말이죠.

```cpp-formatted
/* if 와 if- else if 의 차이*/
#include <stdio.h>
int main() {
  int num;

  printf("아무 숫자나 입력해 보세요 : ");
  scanf("%d", &num);

  if (num == 7) {
    printf("a 행운의 숫자 7 이군요!\n");
  } else if (num == 7) {
    printf("b 행운의 숫자 7 이군요! \n");
  }

  // 비교
  if (num == 7) {
    printf("c 행운의 숫자 7 이군요!\n");
  }
  if (num == 7) {
    printf("d 행운의 숫자 7 이군요! \n");
  }

  return 0;
}
```

성공적으로 컴파일 후, 7 을 입력하였다면

```exec
아무 숫자나 입력해 보세요 : 7
a 행운의 숫자 7 이군요!
c 행운의 숫자 7 이군요!
d 행운의 숫자 7 이군요!
```

와 같이 나오게 됩니다. 여기서 주목해야 할 점은, 출력되는 문장 앞의 알파벳 (a,c,d) 인데 이는 각 문장이 위 프로그램의 어느 부분에서 출력되는 지 알려줍니다.

우리가 컴퓨터 라고 생각하고 프로그램을 실행해 봅시다. 통상적으로 프로그램은 소스코드의 위에서 부터 아래 방향으로 실행됩니다

```cpp-formatted
if (num == 7) {
  printf("a 행운의 숫자 7 이군요!\n");
} else if (num == 7) {
  printf("b 행운의 숫자 7 이군요! \n");
}
```

컴퓨터가 쭉 프로그램을 읽다가 위 부분에 도달하면

"어! `if` 문이군. `num` 의 값이 7 인지 확인해 볼까?" 라고 확인을 합니다. 그런데, 참 이므로
"오, `if` 문이 참 이군. 그렇다면 중괄호 속의 내용을 실행해야겠다! " 하며 "a 행운의 숫자 7 이군요" 를 출력합니다.

그런데, 그 다음 부분인 `else if(num == 7)` 에서도 마찬가지로 `num` 의 값이 7 이므로 `num == 7` 이 참이 되어서 `else if` 가 참이 되어 "b 행운의 숫자 7 이군요! " 도 출력되어야 할 것 같습니다.  하지만, 결과롤 보아하니 출력이 되지 않았습니다. 왜 일까요?

왜냐하면, 앞에서 누누히 설명했듯이 `else` 문은 전제 조건이 '앞의 `if` 문이 참이 아닐 때' 실행 된다는 사실을 기본으로 깔고 있기 때문이죠. 따라서, 앞의 `if` 문이 참이므로 실행이 될 수 없습니다. 따라서, "b 행운의 숫자 7 이군요! " 도 출력되지 않습니다. 참고적으로 `else` 문은 언제나 `if` 문의 결과에 따라 실행 여부가 결정되므로 언제나 `else` 를 사용하려면 `if` 도 반드시 함께 따라 사용해야 합니다.

  다시 컴퓨터가 쭉 읽다가 아래와 같은 문장을 발견했네요.

```cpp-formatted
if (num == 7) {
  printf("c 행운의 숫자 7 이군요!\n");
}
if (num == 7) {
  printf("d 행운의 숫자 7 이군요! \n");
}
```

"어! `if` 문이군. 그런데 `num` 의 값이 7 이므로 이 `if` 문은 참이야. 중괄호 속의 내용을 실행해야지" 하면서 "c 행운의 숫자 7 이군요!" 가 출력된다. 마찬가지로 아래도

"어! `if` 문이군. 그런데 `num` 의 값이 7 이므로 이 `if` 문은 참이야. 중괄호 속의 내용을 실행해야지" 하면서 "d 행운의 숫자 7 이군요!" 가 출력되는 것입니다.

```cpp-formatted
#include <stdio.h>
int main() {
  float ave_score;
  float math, english, science, programming;

  printf("수학, 영어, 과학, 컴퓨터 프로그래밍 점수를 각각 입력해 주세요 ! : ");
  scanf("%f %f %f %f", &math, &english, &science, &programming);

  ave_score =
      (math + english + science + programming) / 4;  // 4 과목의 평균을 구한다.
  printf("당신의 평균 점수는 %f 입니다 \n", ave_score);
  if (ave_score >= 90) {
    printf("당신은 우등생 입니다. ");
  } else if (ave_score >= 40) {
    printf("조금만 노력하세요!. \n");
  } else {
    printf("공부를 발로 합니까? \n");
  }

  return 0;
}
```

만약 성공적으로 컴파일 하였다면

```exec
수학, 영어, 과학, 컴퓨터 프로그래밍 점수를 각각 입력해 주세요 ! : 100
90
90
85
당신의 평균 점수는 91.250000 입니다 
당신은 우등생 입니다. 
```

 와 같이 나오게 됩니다. 그 외에도, 다른 값들을 입력하면 다른 결과가 출력됨을 알 수 있습니다.

```cpp-formatted
ave_score = (math + english + science + programming) / 4;
```

  아마, 산술 연산을 까먹으신 분들은 없겠죠? 위 식이 2 초 내로 이해가 되지 않는다면 [ 4 강](http://itguru.tistory.com/entry/%EC%94%B9%EC%96%B4%EB%A8%B9%EB%8A%94-C-%EC%96%B8%EC%96%B4-4-%EA%B3%84%EC%82%B0%ED%95%98%EB%A6%AC)을 다시 공부하시기 바랍니다.  위 식은, 수학, 영어, 과학, 프로그래밍 점수의 평균을 구해서 `ave_score` 라는 변수에 대입하는 식입니다.

```cpp-formatted
if (ave_score >= 90) {
  printf("당신은 우등생 입니다. ");
} else if (ave_score >= 40) {
  printf("조금만 노력하세요!. \n");
} else {
  printf("공부를 발로 합니까? \n");
}
```

위 프로그램의 핵심 부분(?) 이라 할 수 있는 이 부분을 잘 살펴봅시다. 만약 내 평균 점수가 93 이라면, "당신은 우등생 입니다" 가 출력되게 되죠. 그리고, 아래 `else if` 와 `else` 는 무시하고 종료됩니다.

하지만 평균 점수가 40 이라면, 위의 `if (ave_score >= 90)` 이 거짓이 되어 다음으로 넘어가죠. 즉, `else if (ave_score >= 30)` 을 합니다. 이번에는 참이 되므로, *조금만 노력하세요!* 가 출력이 되고 종료가 됩니다.

또한, 평균점수가 10 점 이라면 위의 `if` 와 `else if` 모두 거짓이지만 `else if(ave_score > 0 )` 은 참이 되어 *공부를 발로 합니까?* 가 출력 됩니다.

마지막으로 평균점수가 0 점 이하 라면, 떨거지 처리(?) 인 `else` 에서 참이 되어서 *인생을 포기하였군요* 가 실행됩니다.

```cpp-formatted
/* 크기 비교 */
#include <stdio.h>
int main() {
  int a;
  printf("아무 숫자나 입력하세요 : ");
  scanf("%d", &a);

  if (a >= 10) {
    if (a < 20) {
      printf(" %d 는 10 이상, 20 미만인 수 입니다. \n", a);
    }
  }
  return 0;
}
```

성공적으로 컴파일 후, 10 이상 20 미만의 수를 입력했다면

```exec
아무 숫자나 입력하세요 : 10
 10 는 10 이상, 20 미만인 수 입니다. 
```

와 같이 나오게 됩니다. 위 소스 코드는 간단합니다. 우리가 여태까지 배운 내용 만으로도 충분히 이해 할 수 있습니다!

```cpp-formatted
if (a >= 10) {
  if (a < 20) {
    printf(" %d 는 10 이상, 20 미만인 수 입니다. \n", a);
  }
}
```

처음에, `a` 의 값이 10 이상이면 참이 되어서 중괄호 속의 내용을 실행하게 되고, 또한 거기서 `a < 20` 이라는 `if` 문을 만나게 되는데 이것 조차 참이라면 `printf` 가 실행되겠지요,.

그런데, 사실 위 문장은 아래와 같이 간단히 줄여 쓸 수 있습니다.


### 논리 연산자

#### 논리 곱 연산자 (Logical AND)

```cpp-formatted
/* 논리 연산자 */
#include <stdio.h>
int main() {
  int a;
  printf("아무 숫자나 입력하세요 : ");
  scanf("%d", &a);

  if (a >= 10 && a < 20) {
    printf(" %d 는 10 이상, 20 미만인 수 입니다. \n", a);
  }

  return 0;
}
```

위 소스를 그대로 컴파일 해 보면 위와 결과가 똑같이 나옵니다. 그렇다면 '&&' 는 무엇일까요? 그 것은 바로 **논리 곱(AND)** 라고 불리는 논리 연산자 입니다. \sidenote{왜 논리 "곱" 이냐면, 곱셈은 둘 중 하나라도 0 이라면 0 이 됩니다. AND 도 마찬가지로 둘 중 하나라도 0 이라면 0 이 되었죠.}

앞에서 우리는 AND 연산에 대해 배운 적이 있었습니다. (기억이 나지 않는다면 [여기를](http://itguru.tistory.com/8) 클릭). 이 때, AND 연산의 특징은 바로 오직 `1 AND 1` 만이 결과가 1 이였고, `1 AND 0` 또는 `0 AND 0` 은 모두 결과가 0 이였습니다.

여기서도 마찬가지 입니다. 위에서도 이야기 했지만 '참' 은 숫자 1 에 대응되고 '거짓' 은 숫자 0 에 대응 됩니다. 따라서, `a >= 10` 이 참이라면 1 을 나타내고, 거짓이라면 0 을 나타낸다고 보시면 됩니다. \sidenote{정확히 말하자면 C 에서 0 은 거짓, 0 이 아닌 모든 값은 참을 나타냅니다.}

마찬가지로, `a < 20` 도 참 이라면 1 을 나타내고, 거짓이라면 0 을 나타냅니다. 만약 `a >= 10` 도 참이고 `a < 20` 도 참 이라면 `1 AND 1` 을 연산하는 것과 같게 되어서 결과가 1, 즉 참이 되어 `if` 문의 중괄호 속의 내용을 실행하게 되죠.

반면에 `a < 10` 라던지 `a >= 20` 이여서 둘 중 하나라도 조건을 만족하지 않게 된다면 `1 AND 0` 이나 `0 AND 1` 을 하는 것과 같게 되어 결과가 `0` 즉 거짓이 됩니다. 따라서 중괄호 속의 내용은 실행되지 않게 됩니다.

정리하자면, `&&` 는 두 개의 조건식이 모두 '참' 이 되어야 `if` 문 속의 내용을 실행하는 것이 됩니다.

### 왜 & 대신에 && 를 쓸까?

그렇다면 우리가 여태 알고 있었던 AND 연산 기호인 `&` 를 쓰지 않고 `&&` 를 쓰는 것일까요? 그 이유는 `&` 하나는, 말 그대로 **비트 사이의 AND 연산**을 사용 할 때 사용하는 것이로, 조건식 사이의 관계를 표현하고 싶다면 논리 곱 연산자인 `&&` 를 사용해야 합니다.

쉽게 말해 `&` 는 정확한 비트 AND 연산 결과를 제공하고, `&&` 는 그냥 참 (= 1) 혹은 거짓 (= 0) 만을 알려줍니다. 따라서 만약에 어떠한 `int` 변수 `a` 와 `b` 사이에 AND 연산을 하고 싶다면 `a & b` 를 해야지, `a && b` 를 하면 올바른 AND 연산을 수행할 수 없습니다. 간단히 아래 예제를 보면 알 수 있습니다.

```cpp
#include <stdio.h>

int main() {
  int a = 31, b = 15;
  printf("a & b = %d\n", a & b);
  printf("a && b = %d\n", a && b);
}
```

성공적으로 컴파일 하였다면

```exec
a & b = 15
a && b = 1
```

흠 그렇다면 반대로 `&&` 자리에 `&` 를 써도 무방할 것 같은데 말이죠. 왜냐하면 위에서도 말했듯이 0 이 아닌 모든 값들은 어차피 참으로 간주되기 때문이죠. 그런데 왜 논리식 사이에는 `&&` 를 사용하는 것이 바람직할까요? 

#### Short Circuit Evaluation

예를 들어서 다음과 같은 문장을 생각해봅시다.

```cpp
if (height >= 180 && weight >= 90) {

}
```

만약에 `height` 가 179 라고 해봅시다. 그렇다면 굳이 그 다음의 조건식인 `weight >= 90` 을 확인해봐야 할까요? 아닙니다. AND 의 경우 어차피 둘 중 하나가 거짓이라면, 그 다음것은 확인해볼 필요도 없이 전체 연산 결과가 거짓임을 알 수 있습니다. 따라서 굳이 `weight >= 90` 을 확인해볼 필요가 없습니다.

위 경우 처럼 한 조건식을 확인하였는데 전체 결과가 정해져 있는 경우, 굳이 그 다음 조건식을 확인할 필요가 없습니다. 이 같은 경우 컴퓨터는 뒤의 조건식을 확인하지 않는데 (쓸데 없는 연산을 줄이기 위해서), 이와 같은 방식을 **Short Circuit Evaluation** 이라고 부릅니다. (줄여서 *SCE* 라고 부릅시다.)

만약에 `height >= 180 & weight >= 90` 처럼 `&` 를 사용하였다면 SCE 를 적용할 수 없습니다. 왜냐하면 `&` 는 정확한 연산 결과를 제공해야 하므로 뒤에 오는 식도 반드시 계산을 해야 하기 때문이죠. 하지만 `&&` 는 논리 결과에 따라서 0 혹은 1 만 돌려주면 되기 때문이므로 SCE 를 사용 할 수 있습니다.

```lec-warning
조건식 사이의 관계를 표현하고 싶다면 반드시 논리 연산자를 사용하세요!
```

#### 논리 합 연산자 (Logical OR)

```cpp-formatted
/* 논리 합 */
#include <stdio.h>
int main() {
  int height, weight;
  printf("당신의 키와 몸무게를 각각 입력해 주세요 : ");
  scanf("%d %d", &height, &weight);

  if (height >= 190 || weight >= 100) {
    printf("당신은 '거구' 입니다. \n");
  }

  return 0;
}
```

성공적으로 실행 후, 키를 190 이상으로 입력했거나 몸무게를 100 이상으로 입력했다면

```exec
당신의 키와 몸무게를 각각 입력해 주세요 : 200 90
당신은 '거구' 입니다. 
```

위와 같이 나오게 되죠.

이번에는 `||` 라는 것이 등장하였습니다. 앞서 AND 가 `&&` 였다는 것을 보아, `||` 는 OR 를 나타내는 논리 연산자임을 알 수 있습니다.

기억을 되살려 봅시다. AND 와 OR 의 차이가 뭐였죠? AND 가 두 조건이 모두 참 일 때, 참을 반환한다면, OR 은 두 조건이 모두 거짓 일 때 만 거짓을 반환합니다. 다시말해 `(참) || (거짓) == (참)` 이 된다는 것이지요.

```cpp-formatted
if (height >= 190 || weight >= 100) 
```

그렇다면 위 `if` 문을 살펴 봅시다. `height >= 190` 이 참 이라면, OR 연산한 값은 `weight` 의 크기에 관계없이 무조건 참이 되어서 중괄호 속의 내용을 실행 합니다. 또한 `height >= 190` 이 거짓이여도, `weight >= 100` 이 참 이라면 중괄호 속의 내용을 실행하게 되죠.

따라서, OR 논리 연산자는 조건식에서 적어도 어느 하나가 참 이라면 무조건 `if` 문의 내용을 실행해 주게 됩니다.

```cpp-formatted
/* 논리 부정 */
#include <stdio.h>
int main() {
  int height, weight;
  printf("당신의 키와 몸무게를 각각 입력해 주세요 : ");
  scanf("%d %d", &height, &weight);

  if (height >= 190 || weight >= 100) {
    printf("당신은 '거구' 입니다. \n");
  }
  if (!(height >= 190 || weight >= 100)) {
    printf("당신은 거구가 아닙니다. \n");
  }

  return 0;
}
```

위 소스를 성공적으로 컴파일 한 후, 180 과 80 을 입력하였다면

```exec
당신의 키와 몸무게를 각각 입력해 주세요 : 180 80
당신은 거구가 아닙니다. 
```

와 같이 나옵니다.

위 소스에서 관심있게 살펴 보아야 할 부분은 바로 이 부분이죠.

```cpp-formatted
if (!(height >= 190 || weight >= 100)) {
  printf("당신은 거구가 아닙니다. \n");
}
```

(참고로 위의 소스와 다른 점은 `height` 앞에 `!` 가 붙었다는 점 입니다.) 다른 것은 다 똑같은데, 새로 붙은 `!` 가 무슨 역할을 하는 것 같나요?

아마도 예측 하셨겠지만, `!` 는 NOT 을 취해주는 연산자 입니다. 다시 말해, **참을 거짓으로, 거짓을 참으로 반전**을 시켜 줍니다. 다시 말해 0 은 1 로, 0 이 아닌 값은 0 으로 변환해줍니다. 

위 경우, `height >= 190 || weight >= 100` 가 **거짓**일 경우에만, 다시 말해서 `height < 190 && weight < 100` 인 경우에만 중괄호 속의 내용이 실행 됩니다.

참고로 `!` 연산자가 0 이 아닌 값은 0 으로 변환해준다는 특성을 이용해서 보통 어떠한 변수의 값이 0 이 아닌지를 판별하기 위해 아래와 같이 작성하기도 합니다.

```cpp
if (!p) { // p == 0 과 같은 의미이지만 더 짧기 때문에 자주 사용된다 :)
  // p 가 0 일 때에만 실행된다.
}
```

### 정리

이것으로 C 언어에서 중요한 부분인 `if` 문에 대해 알아 보았습니다. 이제 마지막으로 할 일은 바로 `if` 문을 가지고 여러가지 프로그램을 만들어 보는 것입니다. 솔직히 말해서, `if` 문 이전까지 배운 내용으로는 그다지 할 것들이 없었습니다.

하지만 이번 `if` 문을 통해서 컴퓨터에게 생각(?) 할 수 있는 능력을 부여 할 수 있게 됩니다. 따라서, 무궁 무진한 것들을 만들어 낼 수 있게 되죠. 뭐, 만들어 볼 것들로 제가 추천하는 것들은 계산기나 성적표라던지, 등등. 아무튼, 힘내세요.

```lec-summary
`if, else if, else` 가 무엇 인지 알고 있습니다.
논리 연산자 `&&, ||` 를 배웠습니다.
`!` 의 역할을 알고 있습니다.
`0 <= a <= 1` 을 잘못된 사용 예 입니다. 이 대신 `0 <= a && a <= 1` 과 같이 사용해야 합니다.
```

##@ chewing-c-end