C 언어 | 흐름 제어 | if문

조건에 따라 실행하는 문장을 선택하는 if 문을 소개한다. if 문을 이용함으로써 상황에 따라 프로그램의 흐름을 변경할 수 있다.

프로그램을 분기시키기

지금까지는 프로그램은 main() 함수의 내부를 위에서 아래로 성실하게 수행하여 왔다. 입력을 배워서 보다 동적인 결과를 얻을 수 있게 되었지만, 프로그램은 항상 1개의 길로 나아갈 뿐이었다.

여기에서는 추가적으로 값을 판정하고 프로그래머의 의도에 따라 프로그램을 동작시킨다. 즉, 프로그램을 분기시킨다. 값을 판단하는 방법은 앞에서 “진위 판정"에서 배웠다.

프로그램을 분기하는 가장 기본적인 제어문은 if 문다. if 문은 “~가 ~하면 ~한다"라는 프로그램 제어를 가능하게 한다. ~가 ~라면이라는 부분은 관계 연산자와 논리 연산자를 이용한 조건식으로 표현할 수 있다.

if 문

if (조건식) 문장

조건식은 참 또는 거짓을 나타내는 값(즉, 결국은 숫자)을 지정한다. if 문은 조건식의 결과가 참인 경우에만 실행되고, 그렇지 않으면 실행되지 않는다. 보다 간단하게 말하면, 조건식에 0이 아닌 값이 지정된 경우에만 실행되는 것이다.

코드1

#include <stdio.h>

int main() {
  int iBool;
  printf("0 또는 다른 값을 입력하십시오. >");
 scanf("%d" , &iBool);

 if (iBool) printf("참이 입력되었습니다.\n");
  if (!iBool) printf("거짓이 입력되었습니다.\n");

  return 0;
}

코드1을 실행하면 값의 입력이 요구되므로 0 또는 다른 값(즉, true 또는 false)을 입력한다. 그러면 프로그램은 if 문에 입력된 값을 판단해 그 결과에 따라 표시하는 문장이 변한다. 첫번째 if 문은 iBool이 참이라면 그 다음의 if 문은 부정 연산자! 부정하고 있기 때문에 iBool이 거짓이면 계속해서 문을 실행한다.

iBool이 거짓이면 실행하는 if 문을 기술할 경우, !iBool 대신 iBool == 0라고 써도 같은 결과를 얻을 수 있다. if (!iBool)라는 문장은 영어권 사람들이 보면 직관적으로 if not iBool 느낄 수 있지만, 한국인은 if (iBool == 0) ...라고 쓰는 것이 이해가 쉬울지도 모른다. 이것은 취향의 문제이다.

코드1은 “~이 참이어야"라는 표현을 !iBool는 부정 연산자를 이용한 if 문에서 실현하고 있다. 그러나 이처럼 iBool을 판단하여 결과를 참일 경우와 거짓일 경우의 두 가지로 분기시키고 싶은 경우는 else부분을 사용하는 방법이 있다. else 부분은 if 문과 한 세트로 사용되는 것으로, if에서 판단한 조건식이 거짓인 경우에 실행된다. else 부분을 이용한 if 문은 다음과 같이 기술한다.

else 부분이 있는 if 문

if (조건식) 문장 1 else  2

if 문 조건식이 참이면 문장1이 실행되고 그렇지 않으면 else 키워드 다음 문장2가 실행된다. else 전에 반드시 if가 필요하며, if 문이 없는 곳에서 else 부분을 지정할 수 없다. else 부분이 있는 if 문을 사용하면 코드1을 다음과 같이 개선할 수 있다.

코드 2

#include <stdio.h>

int main() {
  int iBool;
  printf("0 또는 다른 값을 입력하십시오. >");
  scanf("%d" , &iBool);

  if (iBool) printf("참이 입력되었습니다. \n");
  else printf("거짓이 입력되었습니다. \n");

  return 0;
}

코드2는 코드1을 더 최적화된 방식으로 개량한 것이다. 이와 같이 else 부분을 이용하면 iBool가 가짜인지 여부를 확인할 필요가 없기 때문에 쓸데없는 처리를 생략할 수 있다. else 부분은 if 문 평가가 거짓인 경우에 실행된다. 물론 참이면 else 부분은 실행되지 않는다.

또한 if와 else는 다음과 같이 중첩(같은 형의 상자 등을 크기 순으로 몇개 겹쳐 중으로 들어갈 수 있게 한 것. 프로그래밍에는 동일한 명령을 거듭하는 것을 중첩이라고 함)할 수 있다. 이것은 “~하면 ~한다. 그렇지 않으면 ~한다. 그렇지 않으면 ~ 한다 …“라는 프로그램의 흐름을 만들 수 있도록 되고, 복잡한 제어 및 분석을 할 경우에 일반적으로 사용되는 있다. 다만, 중첩 관계는 가능한 적게하고, 읽기 쉬운 프로그램을 쓸 수 있도록 해야 한다.

코드3

#include <stdio.h>

int main() {
  char chVar;
  printf("Do you like C language? Y/N>");
  scanf("%c" , &chVar);

  if (chVar == 'Y' || chVar == 'y')
    printf("Good! Just go for it!!\n");
  else if (chVar == 'N' || chVar == 'n')
    printf("Why are you studying C language?\n");
  else
    printf("Error\n");

 return 0;
}

코드3은 프로그램에 “당신은 C 언어가 좋아?“라고 질문하고 Y(Yes) 또는 N(No)를 입력하고 질문에 대답하는 일반적인 명령 줄의 대화를 상정한 것이다. 프로그램은 입력된 값을 확인하고, “Y가 입력 된 경우”, “N이 입력 된 경우”, “그 이외의 값이 입력 된 경우"의 3가지 패턴으로 분기시킬 수 있다.

프로그램에서는 첫번째 if 문에서 입력된 문자를 저장하는 chVar 변수를 확인하고, ‘Y’또는 ‘y’중 하나가 입력되어 있는지 여부를 조사하고 있다. 이 판단의 결과가 거짓이면 else가 실행되지만, 이 if 문 else에는 또한 if 문을 이용하고 있기 때문에 중첩 구조로 되어 있다.

복합 문(블록)

지금까지의 프로그램에서는 if와 else 부분에 의해 프로그램을 분기시킬 수 있었지만, 실행할 수 있는 것은 1개의 문장만 이었다. 이것으로는 if 문으로 여러 문장을 지정할 수 없다. 예를 들어, 다음과 같은 프로그램은 잘못된 것이다.

if (exp) 
  iVar += 50;
  printf("iVar = %d" , iVar);
else ...

if 문에서 지정한 조건 exp가 참이면 iVar += 50는 if 문으로 실행되지만 printf()의 시점에서 원래의 제어에 돌아간다. 따라서 else는 직전의 if 문이 존재하지 않는 것으로 판단되는 컴파일 오류가 발생하게된다. if에서 여러 문장을 한꺼번에 실행시키고 싶은 경우, 복합 문(블록라고도 함)를 사용해야 한다.

복합문

{
  문장1
  문장2
  문장N...
}

복합 문은 {로 시작해서 }으로 끝난다. 문장을 작성할 수 있는 장소라면 어디든지 쓸 수 있다. {} 내부는 여러 문장으로 구성되어, 어떤 문장의 본체로서 기능할 수 있다. 예를 들어, 함수의 본체는 복합 문이라고 생각할 수 있다. C 언어는 문장의 끝에 세미콜론;을 지정하는 것이 보통이지만, 복합 문장의 끝에;를 붙이지 않는다. 또한, 복합 문은 중첩될 수 있다.

무언의 규칙으로는 복합 문의 내부는 들여 쓰기를 1단계 깊게하는 규칙이 있다. 이것은 C의 구문이 아니기 때문에, 따르지 않아도 컴파일할 수 있지만, 매우 읽기 어려운 소스가되어 버린다. 만약 다음과 같은 프로그램 소스를 작성했다면, 당신 이외에 읽어주는 사람은 없다고 생각해도 좋을 것이다.

if (a == b) {
printf("...");
if (a == c) {
printf("...")
}
}
else {
printf("...");
}

공동 개발과 오픈 소스 개발을 생각해서. 초반부터 올바른 소스 작성을 습관화하자. 통합 개발 환경의 프로그래밍 전용 편집기에서 자동으로 변경해 주기도 하지만, 간단한 텍스트 편집기를 사용하는 경우는 의식 할 필요가 있다. 다음과 같이 기술하면 쉽게 읽을 수 있다.

if (a == b) {
 printf("...");
  if (a == c) {
   printf("...")
 }
}
else {
  printf("...");
}

이렇게 기술하게 것으로, 문장이 어떤 복합 문에 속해 있는지를 판단하기 쉬워진다.

코드4

#include <stdio.h>

int main() {
  int iBool;
  printf("0 또는 다른 값을 입력하십시오. >");
 scanf("%d" , &iBool);

 if (iBool) {
    printf("참이 입력되었습니다.\n");
   return 1;
 }
 else {
    printf("거짓이 입력되었습니다.\n");
    return 0;
 }
}

이 프로그램은 참 또는 거짓을 나타내는 숫자를 입력하고, 그 결과에 따라 시스템에 반환 값을 변화시키고 있다. 중첩된 복합 문장의 내부에서 함수를 종료시킬 수 있기 때문에, if와 else에서 지정하고 있는 복합 문 내부에서 프로그램을 종료한다.

코드4의 if-else 문 처리는 printf() 함수와 return 키워드를 이용한 2개의 문장으로 구성되어 있기 때문에 하나의 문장으로 표현할 수 없다. 그래서 복합 문을 사용하여 여러 문장을 지정하고 있다. return이 반환 값이 어떻게 이용되는지는 시스템에 따라 다르다. 자세한 내용은 당신이 사용하고 있는 시스템에 대한 자세한 내용 공부하도록 한다. 시스템에 반환 값의 그 후는 C 언어의 관할이 아닌 것이다.