끝나지 않는 프로그래밍 일기


1. if~else(만약에~)


우리가 배울 제어문이란 말 그대로 프로그램의 실행 흐름을 제어하며 C언어에서는 조건문과 반복문을 제공합니다. 조건문은 우리가 특정 조건을 부여하고 그 조건이 만족하면 해당 문장을 수행할수 있는 문법입니다. 이 조건이 참(TRUE)이면 if문 내의 코드를 실행하며 거짓(FALSE)이면 if문 내의 코드를 실행하지 않고 그냥 넘겨버립니다. 조건은 수식으로 주어집니다. if 문의 구조를 보시면 다음과 같습니다.

if (조건문) {
 조건식이 만족되면 실행될 문장;
}

조건문에 오는건 반드시 참(true) 혹은 거짓(false)이여야 하며, 주로 논리 연산자와 비교 연산자 등이 조건문에 쓰입니다. if문을 사용하기 전, 간단한 비교 연산자부터 짚고 넘어가도록 하겠습니다. 한번 아래의 표를 봅시다.


연산자

연산의 예

의미

<

a < b

a가 b보다 작은가

>

a > b

a가 b보다 큰가

==

a == b

a와 b가 같은가

!=

a != b

a와 b가 같지 않은가

<=

a <= b

a가 b보다 작거나 같은가

>=

a >= b

a가 b보다 크거나 같은가


수학에서 쓰는 등호, 부등호와 비슷하며 여기서 주의하실 점은 <=, >=는 허용되나 =<, =>는 허용되지 않습니다. 한번, 위의 비교 연산자들을 직접 사용해보도록 합시다.

#include <stdio.h>

int main()
{
 int a, b;

 scanf("%d %d", &a, &b);
 if (a<b)
  printf("b가 a보다 큽니다.\n");
 if (a>b)
  printf("a가 b보다 큽니다.\n"); 
 if (a==b)
  printf("a와 b가 같습니다.\n");
 if (a!=b)
  printf("a와 b가 같지 않습니다.\n");
 if (a<=b)
  printf("a가 b보다 작거나 같습니다.\n");
 if (a>=b)
  printf("a가 b보다 크거나 같습니다.\n");

 return 0;
}

결과:

4 7

b가 a보다 큽니다.
a와 b가 같지 않습니다.
a가 b보다 작거나 같습니다.


우리가 여기서 만약 위의 예제에서 4와 7이란 수를 입력했다면 a<b, a!=b, a<=b와 같은 비교 연산을 만족하여 위와 같은 출력 결과를 얻을 수 있습니다. 그리고 원래는, if문 안에 오는 코드들은 모두 괄호를 사용하여 묶어주어야만 하는데, 내부에 있는 코드가 한줄이라면 중괄호를 생략할 수 있습니다. (여러개의 명령을 묶을때 중괄호 사용)


만약에, 모든 조건이 충족되지 않을 경우에는 어떠한 메시지를 출력하고 싶을 경우는 어떻게 해야 할까요? 이 경우에는, 바로 else 라는 녀석을 사용하면 됩니다. 이 else문은 조건을 모두 충족하지 않을 경우 어떤 특정한 문장을 실행하려 할때 지정하며, 이 else문은 if문에 종속적입니다. 즉, if문 없이는 else문 혼자서 독립적으로 쓰일 수 없다는 말입니다. 반드시 if문과 함께 쓰여야 한다는 소리입니다. 한번 예제를 직접 보도록 할까요?

#include <stdio.h>

int main()
{
 int a;

 scanf("%d", &a);

 if (a==2)
  printf("2가 입력되었습니다.\n");
 else
  printf("2가 아닌 다른 수가 입력되었습니다.\n");
 
return 0;
}

결과:

4

2가 아닌 다른 수가 입력되었습니다.


위의 예제는 대략적으로 살펴보면 다음과 같습니다. 사용자로부터 a의 값을 입력받고 그 a의 값이 2라면 "2가 입력되었습니다"를 출력하고 만약 그렇지 않을 경우에는, "2가 아닌 다른 수가 입력되었습니다."가 출력되는 것입니다. 그리고 else뿐만 아니라, else if란 녀석도 있는데 이 녀석도 else문 처럼 if문에 종속적이며, 필요하다면 얼마든지 추가해도 됩니다. 아래 예제를 통해 else if를 간단히 이해하도록 합시다.

#include <stdio.h>

int main()
{
 int a;

 scanf("%d", &a);

if (a==2) // a가 만약 2라면
 printf("2가 입력되었습니다.\n");
else if (a==3) // a가 2가 아닌 3이라면
 printf("3이 입력되었습니다.\n");
else // 위의 조건들을 모두 만족하지 않는다면
 printf("2와 3이 아닌 다른 수가 입력되었습니다.\n");

 return 0;
}

결과:

3

3이 입력되었습니다.


위의 예제에서는 입력된 a의 값이 2라면 2가 입력되었다는 문장을, 3이라면 3이 입력되었다는 문장을, 2도 아니고 3이 아니라면 2와 3도 아닌 다른 수가 입력되었다는 문장을 출력하도록 했습니다. 자, 이 else if란 녀석이 일반 if문과 다른점은 예를 들어, 위의 예제에서 2가 입력되었다면 a와 2가 같은지 비교를 하는 구간에서 참이되어 코드를 실행하고 빠져나옵니다. 그리고 3이 입력되었을 경우, a는 2와 같지 않으므로 다음 비교에서 3과 같은지 비교를 하게 되는데 이 경우 조건이 성립하므로 이 구간의 코드를 실행하고 빠져나옵니다. 만약에, 아래와 같이 if문 만으로 예제를 작성했다면 어땠을까요?

if (a==2)
 printf("2가 입력되었습니다.\n");
if (a==3)
 printf("3이 입력되었습니다.\n");
if (a==4)
 printf("4가 입력되었습니다.\n");

if (a==2)
 printf("2가 입력되었습니다.\n");
else if (a==3)
 printf("3이 입력되었습니다.\n");
else if (a==4)
 printf("4가 입력되었습니다.\n");

위 두 예제는 둘다 같은 결과를 출력합니다. 그렇지만 2를 입력했다 가정하고, 1번 예제 같은 경우는 첫번째 if문의 조건 검사를 수행하고, 두번째, 세번째도 함께 거치게 됩니다. 이것은 불필요한 비교 연산이며 비효율적인 코드가 아닐 수 없습니다. a가 2임을 이미 확인했는데, 3과 4와 같은지 비교하는 연산은 더이상 불필요한 연산이겠죠?


2번 예제는 첫번째 if문의 조건 검사를 거치고 2와 일치하여 조건을 만족시키고 빠져나옵니다. 만약에 3을 입력했다면 첫번째와 두번째의 if문을 거치게 됩니다. 이해 되셨나요?

참고로, 우리가 배운 if~else문은 중첩이 가능하여 다음과 같이 확장시킬 수 있습니다.

if (a==11) {
 printf("11이 입력되었습니다.");
 if (a>10)
  printf("입력된 값이 10보다 큽니다.");
}

이는 if문 안에서 또 다른 if~else문을 사용할수 있다는 말입니다. 물론, 중첩 횟수는 제한되어 있는게 아닌 필요에 의해서 계속 중첩이 가능하다는 사실! 잊지마시고 기억해두세요. 그리고 추가로, 비교 연산자에 이어서 논리 연산자에 대해 간단히 알아보도록 하겠습니다. 아래 표를 한번 살펴보고, 논리 연산자가 어떤 녀석인지 대충 짐작을 해보도록 합시다.


연산자

의미

수식 예

수식의 의미

&&

논리곱(AND)

a && b

a와 b가 모두 참이면 참이 된다.

||

논리합(OR)

a || b

a와 b중에서 적어도 한쪽이 참이면 참이 된다.

!

논리 부정(NOT)

!a

a가 참이면 거짓이 되고, 거짓이면 참이 된다.


논리 연산자를 어렵게 받아들이실 필요는 없습니다. 논리 연산자는 주로 관계 연산자와 함께 사용되며 두개 이상의 조건식을 결합하여 하나의 진리값을 만들어 냅니다. && 연산자 같은 경우는 아래와 같이 사용이 가능합니다.

if (a==11 && a>10)
 printf("a가 11과 같고 10보다 큽니다.");

위의 예는 a==11과 a>10을 둘다 만족해야 if문 내의 코드를 실행합니다. 만약에 한 조건만 만족하고 다른 조건은 만족하지 않으면 코드가 실행되지 않습니다. 그리고 || 연산자 같은 경우는 아래와 같이 사용이 가능합니다.

if (a==5 || a==7)
 printf("a가 5이거나 7입니다.");

위의 예는 a==5와 a==7을 둘 중 하나만 만족해도 코드를 실행합니다. a가 5일 경우에도, 7일 경우에도 if문 내의 코드가 실행될 수 있습니다. 마지막으로 ! 연산자 같은 경우는 아래와 같이 사용이 가능합니다.

if (!(a==1))
 printf("1이 아닙니다.");

위의 예는 a==1 조건의 결과를 부정하여 역조건으로 만들어 줍니다. 원래는 a가 1이면 조건이 수행되나 ! 연산자가 앞에 붙었으므로 1이 아닐때 코드를 실행하게 됩니다. 차근차근 살펴보면, a가 4가 입력되었다고 가정하면 a==1와 같은 비교 연산에서 거짓(false)이 나오겠죠? 그런데 앞에 논리를 부정하는 ! 연산자가 붙었네요. 이렇게 되면, 아까 나온 거짓(false)이 부정되어 참(true)이 나오는 것입니다.


여기까진 간단히 설명하였고, 만약 이해가 아직도 되지 않으신다면 아래 진리표를 한번 참고해보시길 바랍니다.


논리 연산

A

B

Y

NOT

(논리 부정)

0

 

1

1

 

0

AND

(논리곱)

0

0

0

0

1

0

1

0

0

1

1

1

OR

(논리합)

0

0

0

0

1

1

1

0

1

1

1

1

 

2. switch, case


이제는 switch 문에 대하여 알아볼텐데, 이 switch문은 if~else문이 길어질때 코드를 간결하게 표현할 수 있으며 if 문과 비슷합니다. 이 switch를 다중 선택문이라고도 합니다. 기본 구성은 다음과 같습니다.

...
switch (num) {
 case 1:
  printf("num은 1입니다.\n");
 case 2:
  printf("num은 2입니다.\n");
 case 3:
  printf("num은 3입니다.\n");
 default:
  printf("1도 아니고 2도 아니고 3도 아닙니다.\n");
}
...

우선 이 switch문을 이해하려면 case와 default가 지니는 의미부터 이해하여야 합니다. case와 default문은 뭘까요? 우선은 이것들을 가르켜 레이블(label)이라고 하며 레이블은 '위치를 표시해 두기 위해서 사용되는 것'입니다. 그리고 default란 녀석은, if~else문에서 else와 같은 존재이며 위에서 해당하는 레이블이 없을 경우에는 default문 아래의 코드가 실행됩니다.


위 코드를 살펴보시면 3이라는 레이블이 있습니다. 이것은 'num이 3이면 이 위치에서부터 시작하겠다' 라는 의미를 가집니다. 한번 num에다 2라는 값을 집어넣어두고, 컴파일 하여 결과를 확인해보세요.


결과:

2
num은 2입니다.
num은 3입니다.
1도 아니고 2도 아니고 3도 아닙니다.


어라? 결과를 보니 왜 'num은 2입니다'만 출력되지 않고 엉뚱한 문장까지 출력되는 것일까요? case를 끝낼때는 break문이 필요하며 이 break문을 사용하면 해당 문장만 출력하고 바로 switch 문 밖으로 빠져나가게 됩니다. 위 예제에 break 문을 사용하여 정확한 문장만 출력시키고 빠져나가도록 코드를 수정하면 아래와 같아집니다.

...
switch (num) {
 case 1:
  printf("num은 1입니다.\n");
  break;
 case 2:
  printf("num은 2입니다.\n");
  break;
 case 3:
  printf("num은 3입니다.\n");
  break;
default:
  printf("1도 아니고 2도 아니고 3도 아닙니다.\n");
  break;
}
...

만약에 위의 예제에서 num 값이 3이라면 3 레이블으로 이동하여 'num은 3입니다.'를 출력시키고 break문을 만나 switch문을 탈출합니다. case 옆에는 정수형과 열거형, 문자형이 올수있으며 실수형, 또는 사용자 정의형은 올수 없습니다. default문이 필요하지 않다면 없앨수 있으며 case의 순서를 뒤섞어도 상관이 없습니다. 그리고 위에서 겪었듯이 case 문에서 순서대로 실행하다 break문이 없으면 다음 case의 명령까지 계속 실행합니다. 이를 이용하여 아래와 같은 처리를 할수 있습니다.

...
switch (num) {
 case 1:
 case 3:
 case 5:
 case 7:
 printf("num은 1이거나, 3이거나, 5이거나, 7입니다.\n");
}
...

여러 줄에 존재하는 case 레이블을 한줄로 표현할 수도 있습니다.

...
switch (num) {
 case 1: case 3: case 5: case 7:
  printf("num은 1이거나, 3이거나, 5이거나, 7입니다.\n");
}
...