C언어 기본 입문 - 분기 구조

C언어는 구조화된 프로그래밍 언어로, 여기서 구조는 순차 구조, 선택 구조, 반복 구조를 의미하며, 이는 우리 일상생활에서도 흔히 볼 수 있는 세 가지 구조입니다.

C언어에서는 if, switch를 사용하여 분기 구조를 구현하고, for, while, do while을 사용하여 반복 구조를 구현할 수 있습니다. 이 글에서는 분기 구조에 대해 학습합니다.

1. if 문

1.1 if

if 문의 기본 문법은 다음과 같습니다:

if ( 조건식 )
{
      실행문
}

if 문은 조건식이 참(true)일 때 실행문을 실행하고, 조건식이 거짓(false)일 때 실행문을 실행하지 않습니다. C언어에서는 0은 거짓, 1은 참을 의미합니다.

예제: 정수를 입력받아 홀수인지 판별

#include <stdio.h>

int main()
{
	int number;
	printf("정수를 입력하세요: ");
	scanf("%d", &number);

	if (number % 2 != 0) {
		printf("%d는 홀수입니다.\n", number);
	}

	return 0;
}

if 문에서 {...}가 생략된 경우, if 문 바로 다음에 오는 첫 번째 실행문만 if 문의 제어를 받습니다.

예제: n이 5보다 클 때 "HelloWorld" 출력

if ( n > 5 )
   printf("HelloWorld\n"); // if 조건은 이 문장만 제어
   printf("이 문장은 if 문의 영향을 받지 않습니다.\n");

1.2 else

위에서는 홀수만 판별했지만, 짝수는 어떻게 판별할까요? 또는 임의의 수를 입력받아 홀수인지 짝수인지 한 프로그램에서 판별할 수 있을까요? 이때 if...else... 문이 사용됩니다. 기본 문법은 다음과 같습니다:

if ( 조건식 )
{
     참일 때 실행문
}
else
{
     거짓일 때 실행문
}

예제: 정수를 입력받아 홀수인지 짝수인지 판별

#include <stdio.h>

int main()
{
	int number;
	printf("정수를 입력하세요: ");
	scanf("%d", &number);

	if (number % 2 != 0) {
		printf("%d는 홀수입니다.\n", number);
	} else {
		printf("%d는 짝수입니다.\n", number);
	}

	return 0;
}

연습 문제: 나이를 입력받아 18세 이상이면 "성인", 그렇지 않으면 "미성년" 출력

#include <stdio.h>

int main()
{
	int age;
	printf("나이를 입력하세요: ");
	scanf("%d", &age);

	if (age >= 18) {
		printf("성인\n");
	} else {
		printf("미성년\n");
	}

	return 0;
}

1.3 중첩 if

if else 문에서 else는 다른 if 문과 함께 사용되어 다중 조건 판단을 할 수 있습니다. 예를 들어, 정수를 입력받아 0인지, 양수인지, 음수인지 판별하는 경우입니다. 코드는 다음과 같습니다:

#include <stdio.h>

int main()
{
	int num;
	printf("정수를 입력하세요: ");
	scanf("%d", &num);

	if (num == 0) {
		printf("입력한 숫자는 0입니다.\n");
	} else if (num > 0) { // 이 if 문은 else 문 안에 포함되어 중첩 구조를 형성합니다.
		printf("입력한 숫자는 양수입니다.\n");
	} else {
		printf("입력한 숫자는 음수입니다.\n");
	}

	return 0;
}

이는 전형적인 if 중첩 구조입니다.

1.4 미아(dangling) else 문제

여러 개의 if와 else가 있을 때, else는 가장 가까운 if 문과 짝을 이룹니다.

다음 코드를 살펴보겠습니다:

#include <stdio.h>

int main()
{
	int a = 0;
	int b = 2;

	if (a == 1) {
		if (b == 2) {
			printf("hehe\n");
		}
	} else {
		printf("haha\n");
	}

	return 0;
}

초보자들은 a가 1이 아니므로 "haha"가 출력될 것이라고 생각할 수 있습니다. 하지만 이 코드를 실행하면 아무것도 출력되지 않습니다. 이는 들여쓰기 상으로는 첫 번째 if 문과 else가 짝을 이루는 것처럼 보일 수 있지만, 실제로는 가장 가까운 if 문, 즉 두 번째 if 문과 else가 짝을 이룹니다. 또한, a == 1이 거짓이므로, 이후의 b == 2에 대한 if else 전체가 건너뛰어지고 바로 return 0으로 이동하기 때문입니다.

2. 연산자

프로그래밍에서 연산자는 특정 작업을 수행하기 위한 기호 또는 키워드이며, 그 의미는 피연산자의 타입에 따라 결정됩니다. 여기서는 관계 연산자, 조건 연산자, 논리 연산자에 대해 학습합니다.

2.1 관계 연산자

C언어에서 비교에 사용되는 표현식을 "관계식"이라고 하며, 여기서 사용되는 연산자를 관계 연산자라고 합니다. 주요 관계 연산자는 다음과 같습니다:

  • > (크다)
  • < (작다)
  • >= (크거나 같다)
  • <= (작거나 같다)
  • == (같다)
  • != (다르다)

예제: a > b, a < b, a >= b, a <= b, a == b, a != b

관계 연산자는 주로 ifwhile 문에서 사용됩니다:

if( a > b )
{
    실행문1
}

while(a < b)
{
    실행문2
}

주의사항:

  1. =와 ==는 다릅니다. =는 대입 연산자로, a = b는 b의 값을 a에 대입하는 것을 의미합니다. ==는 관계 연산자로, a == b는 a와 b가 같은지를 비교합니다.
  2. 여러 연산자를 연속으로 사용하는 것은 권장되지 않습니다.
    a < b < c
        
    위 표현식은 문법적으로는 올바르지만, 의도한 대로 동작하지 않을 수 있습니다. 관계 연산자는 왼쪽 결합(왼쪽에서 오른쪽으로 계산)이므로, 먼저 a < b가 계산되어 0(거짓) 또는 1(참)이 반환된 후, 이 값과 c가 비교됩니다. 따라서 다음과 같이 사용하는 것이 일반적입니다:
    a < b && b < c
        
    이는 뒤에서 설명할 논리 연산자를 사용하여 구현합니다.

2.2 조건 연산자 (삼항 연산자)

조건 연산자는 세 개의 피연산자를 필요로 하며, 형식은 다음과 같습니다:

조건식 ? 참일 때 값 : 거짓일 때 값

조건 연산자는 먼저 조건식을 평가합니다. 조건식이 참이면 두 번째 피연산자의 값을 반환하고, 거짓이면 세 번째 피연산자의 값을 반환합니다.

예제: 두 수 중 큰 값을 조건 연산자를 사용하여 찾기

#include <stdio.h>

int main()
{
	int num1, num2;
	printf("두 정수를 입력하세요: ");
	scanf("%d %d", &num1, &num2);

	int max_val = (num1 > num2) ? num1 : num2; // 조건 연산자

	printf("더 큰 수는: %d\n", max_val);

	return 0;
}

여기서 max_val = (num1 > num2) ? num1 : num2;는 num1이 num2보다 큰지 판단하고, 참이면 num1을, 거짓이면 num2를 max_val에 저장합니다. 삼항 연산자에는 괄호를 사용하여 우선순위를 명확히 하는 것이 좋습니다.

2.3 논리 연산자

논리 연산자는 논리 연산을 수행하며, 주요 논리 연산자는 다음과 같습니다:

  • 논리 AND : &&
  • 논리 OR : ||
  • 논리 NOT : !

1. 논리 AND (&&)

식1 && 식2 형태에서, 식1과 식2 둘 다 참일 때만 전체 결과가 참이 됩니다. 하나라도 거짓이면 전체 결과는 거짓입니다.

예제: 세 수 a, b, c를 입력받아 a가 b보다 크고, 동시에 a가 c보다 클 때 a+b+c의 합을 출력

#include <stdio.h>

int main()
{
	int a, b, c;
	printf("세 정수를 입력하세요: ");
	scanf("%d %d %d", &a, &b, &c);
	int sum = a + b + c;

	if (a > b && a > c) {
		printf("합계: %d\n", sum);
	} else {
		printf("조건을 만족하지 않습니다.\n");
	}

	return 0;
}

만약 a=9, b=7, c=5를 입력하면 합계가 출력됩니다. 하지만 a=7, b=5, c=9를 입력하면 합계가 출력되지 않습니다. 이는 a > c 조건이 거짓이기 때문입니다.

2. 논리 OR (||)

식1 || 식2 형태에서, 식1 또는 식2 중 하나라도 참이면 전체 결과가 참이 됩니다.

예제: 세 수 a, b, c를 입력받아 a가 b보다 크거나, 또는 a가 c보다 클 때 a+b+c의 합을 출력

#include <stdio.h>

int main()
{
	int a, b, c;
	printf("세 정수를 입력하세요: ");
	scanf("%d %d %d", &a, &b, &c);
	int sum = a + b + c;

	if (a > b || a > c) {
		printf("합계: %d\n", sum);
	} else {
		printf("조건을 만족하지 않습니다.\n");
	}

	return 0;
}

a=7, b=9, c=3을 입력하면, a > b는 거짓이지만 a > c는 참이므로 합계가 출력됩니다. 단축 평가(short-circuit evaluation): || 연산에서 왼쪽 피연산자가 참이면 오른쪽 피연산자는 평가되지 않습니다.

3. 논리 NOT (!)

!식 형태는 식의 논리적 값을 반전시킵니다. 참을 거짓으로, 거짓을 참으로 만듭니다.

예제: 입력받은 값이 0(거짓)일 때 "haha" 출력

#include <stdio.h>

int main()
{
	int value;
	printf("정수를 입력하세요: ");
	scanf("%d", &value);

	if (!value) { // value가 0 (거짓)이면 참이 됩니다.
		printf("haha\n");
	} else {
		printf("입력값은 0이 아닙니다.\n");
	}

	return 0;
}

value가 0일 때 "haha"가 출력되고, 다른 값이 입력되면 "입력값은 0이 아닙니다."가 출력됩니다.

3. switch 문

switch 문은 분기 구조에서 중요한 문법이며, 기본 형식은 다음과 같습니다:

switch ( 제어식 )
{
    case 값1:
        실행문1;
        break;
   
    case 값2:
        실행문2;
        break;

    default :
        기본 실행문;
        break;
}

제어식의 값과 각 case의 값을 비교하여 일치하는 경우 해당 case의 실행문을 실행합니다. 일치하는 case가 없으면 default 실행문을 실행합니다. break 문은 해당 case 블록을 빠져나가는 역할을 합니다.

주의사항:

  1. 대부분의 경우 각 case 문 뒤에는 break 문이 와야 합니다.
  2. switch 문의 제어식은 정수형이어야 하며, 실수형은 사용할 수 없습니다.

예제: 간단한 메뉴 선택 프로그램

#include <stdio.h>

int main()
{
	int choice;
	printf("메뉴 선택 (1: 게임 시작, 2: 종료): ");
	scanf("%d", &choice);
	
	switch (choice)
	{
	case 1:
		printf("게임을 시작합니다.\n");
		break;
	case 2:
		printf("게임을 종료합니다.\n");
		break;
	default:
		printf("잘못된 입력입니다. 다시 시도해주세요.\n");
		break;
	}

	return 0;
}

태그: C언어 분기문 if else switch

7월 16일 02:33에 게시됨