cyphen156

Chapter5 조건문 : If와 Switch 본문

프로그래밍/C언어

Chapter5 조건문 : If와 Switch

cyphen156 2023. 6. 2. 14:31

조건문

조건문 = 분기점!

조건문에서는 주어진 조건에 따라 참과 거짓으로 나뉘어 실행할 코드의 분기를 결정하는데 사용됩니다. 

만약 조건문 괄호 안의 연산이 참이면 코드를 실행하고, 거짓이면 실행하지 않고 다음 코드를 실행하거나, 다른 조건을 연산한 뒤 코드를 실행합니다. 

If else조건문

// 예제 5-1
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

void Odd_Even(int n) {
	if (n % 2 == 1) {	// 만약 괄호안의 조건이 참이면 바로 아래 중괄호 안의 명령을 실행하고, 
		printf("Odd number.\n");
	}
	else {			// 거짓이면 아래 명령을 실행한다.
		printf("Even number.\n");
	}
	return;
}

int main() {
	int num;
	printf("Enter an integer.\n");
	scanf("%d", &num);
	Odd_Even(num);
	return 0;
}

예제 5-1의 Odd_Even함수의 조건 흐름도

기본적으로 if문은 if와 else로 구분된다 조건이 참인 경우 if문 아래의 중괄호에 해당하는 코드가 실행되고, 아닌 경우에는 바로 다음 코드로 넘어가거나 else문 아래의 중괄호 안에 있는 코드가 실행된 뒤 다음 명령어를 실행한다.

 

그런데 만약 조건이 한가지가 아닌 경우에는 어떻게 해야 할까요?

조건이 (n > 10)인 경우

또는

(n > 10 그리고 b > 100)인 경우 등 여러가지 조건이 생기는 경우가 있을 수 있습니다. 

예시를 하나 들어볼까요? 어떤 학생의 성적을 입력받아 등급을 계산하는 프로그램을 만든다고 했을때 0~100점 사이의 나올수 있는 결과는 A, B, C, D, F의 5가지가 있을 수 있습니다. 

#define	_CRT_SECURE_NO_WARNINGS

#include <stdio.h>

int main() {
	int Score;
	scanf("%d", &Score);		//성적을 입력받고
	if (Score < 0 || Score > 100) {	//만약 입력받은 값이 비정상적이면
		printf("Score Err \n");	//에러메세지를 출력하고 
		return 0;		//프로그램을 종료
	}
	if (Score >= 90)	{	//90~100점 사이의 경우 A
		printf("A");
	} else if (Score >= 80) {	//80~89점 사이의 경우 B
		printf("B");
	} else if (Score >= 70) {	//70~79점 사이의 경우 C
		printf("C");
	} else if (Score >= 60)		//60~69점 사이의 경우 D
		printf("D");
	else				//그 외에는 모두 F
		printf("F");
	return 0;
}

조건이 많아졋죠? 우선 맨 처음에 0~100이외의 경우를 모두 처리한 뒤

점수가 특정 범위에 속하면 등급을 산출해 출력문으로 알려주는 것 입니다.

맨 처음에 나오는 if문은 조건을 체크하는 필수적인 요소로 조건문을 사용할 때 꼭 있어야 하지만 else if는 if문에 걸리지 않은 또 다른 조건을 체크할 때, else는 if조건과 else if 조건에 걸리지 않은 그 외의 것들에 대한 사항을 처리하라는 명령으로 프로그램을 만든 사람의 의도에 따라 있어도 되고 없어도 됩니다.

그런데 조건문을 사용하는 방법은 하나가 아닙니다.

#define	_CRT_SECURE_NO_WARNINGS

#include <stdio.h>

int main() {
	int Score;
	scanf("%d", &Score);			//성적을 입력받고
	if ((0 <= Score) && (Score <= 100)) {	//만약 입력받은 값이 0~100사이의 값을 가지고 있다면 
		if (Score >= 90) {		//90~100점 사이의 경우 A
			printf("A");
		} else if (Score >= 80) {	//80~89점 사이의 경우 B
        		printf("B");
		} else if (Score >= 70) {	//70~79점 사이의 경우 C
			printf("C");
        	} else if (Score >= 60)	{	//60~69점 사이의 경우 D
        		printf("D");
		}else				//그 외에는 모두 F
			printf("F");
        }
	return 0;
}

달라진 것을 느끼셨나요? 첫번째 if 문의 조건이 0~100사이의 유효한 값을 입력받으면 추가 조건을 체크하여 성적을 산출하고 0~100이외의 값인 경우 아무런 동작도 하지 않고 프로그램을 종료합니다.

이렇게 조건문 안에 또 다른 조건문이 있는 경우를 중첩 조건문이라고 합니다.

이렇게 여러가지 경우의 수가 나올 수 있기 때문에 코드를 짠 프로그래머의 생각을 읽는것이 중요합니다.

추가로 조건문 안에서 실행할 내용들을 {}(중괄호)를 사용해서 표시하지만 실행해야 하는 코드가 1줄인 경우에는 중괄호를 생략 할 수 있습니다.

그런데 주의할 점들이 있습니다.

  1. 조건문 안에 대입연산자(=)을 사용하지 않기 : 전에도 말햇든이 =과 ==은 다른겁니다. 조건식에 대입연산자를 사용하면 안됩니다. 만약 사용한다면 컴퓨터는 사용자가 일부러 대입하라 한 것인줄 알기 때문에 오류(Err)를 찾아내기 힘들어집니다.
  2. 데이터 유형의 일치: 비교하려는 값들이 같은 데이터 유형인지 확인해야 합니다. 예를 들어, 정수와 부동소수점 수를 비교하면 예상치 못한 결과가 발생할 수 있습니다.
  3. 부동소수점 수의 비교: 부동소수점 수를 비교할 때는 주의해야 합니다. 컴퓨터에서는 근사치를 사용하여 부동소수점 수를 표현하기 때문에, 예상하는 값과 실제 값이 약간 다를 수 있습니다. 이를 해결하기 위해 주로 작은 "오차" 값(예: 0.00001)을 사용하여 두 부동소수점 수가 충분히 가까운지 확인합니다.
  4. NULL 값과의 비교: NULL 포인터나 값과 비교할 때는 항상 주의해야 합니다. NULL 값을 참조하려고 하면 프로그램이 예상치 못한 방식으로 동작하거나 중단될 수 있습니다.
  5. 문자열 비교: C언어에서 문자열을 비교할 때는 == 연산자를 사용하지 않습니다. == 연산자는 문자열의 내용을 비교하는 것이 아니라, 문자열의 주소를 비교합니다. 따라서 문자열의 내용을 비교하려면 strcmp와 같은 문자열 비교 함수를 사용해야 합니다.
  6. 비교 연산자의 우선 순위: 비교 연산자는 산술 연산자보다 우선 순위가 낮습니다. 따라서 복잡한 표현식에서 비교를 수행할 때는 괄호를 사용하여 의도한 순서를 명확히 표현해야 합니다.
  7. If, else, else if문은 먼저 만난 조건이 참이면 그 뒤에 나오는 조건들을 아예 테스트하지 않습니다. 그래서 조건문을 작성할때에는 조건 연산의 순서를 고려해야 합니다.
  8. 들여쓰기와 중괄호를 쓰자 : 들여쓰기를 하고, 중괄호를 사용하여 조건문의 경계를 명확하게 해주면 프로그램의 알고리즘 파악에 상당한 도움이 됩니다. 만약 하지 않는다면 나중에 어떤 부분에서 실수를 했는지 찾기 번거로워집니다.

삼항연산자

삼항연산자는 연산에 사용되는 기호가 3개라는 것이다. 형태는 (a > b) ? A : B;의 형태로 사용됩니다.

만약 조건문 (a > b)의 결과가 참이면 A를 실행하고, 거짓이면 B를 실행하라는 if else문의 축약형이라 볼 수 있습니다.
주의해야 할 점은 A와 B에 들어오는 식이 대입문일 경우 (A/B)의 형식으로 괄호를 쳐야한다는 것 입니다. 안그러면 컴파일러가 식을 이상하게 인식 할 수 있기 때문입니다.

switch 조건문

if - else 조건문과는 다른 또 하나의 조건문은 Switch - case 조건문 입니다.

이 조건문은 조건문이 세분화 되어야 할 경우 주로 사용됩니다. 

예를 들어 

#define	_CRT_SECURE_NO_WARNINGS

#include <stdio.h>

void comment(char);

int main(void) {
	char grade;
	printf("Enter your grade in capital letter. __\b\b");
	scanf("%c", &grade);
	comment(grade);
	return 0;
}

void comment(char ch) {
	if (ch == 'A')
		printf("Exellent.\n");
	else if (ch == 'B')
		printf("Good.\n");
	else if (ch == 'C')
		printf("Not Bad.\n");
	else if (ch == 'D')
		printf("Need effort.\n");
	else if (ch == "F")
		printf("You can do better than this.\n");
	else
		printf("No such grade.\n");
}

이렇게 여러개의 조건문을 체크하다 보면 논리의 흐름이 끊어질 수 있는데, switch case는 조건(ch)의 Case에 따라 실행되는 명령문을 분류하여 프로그래머가 코드를 이해하는데 도움을 줍니다.

#define	_CRT_SECURE_NO_WARNINGS

#include <stdio.h>

void comment(char);

int main(void) {
	char grade;
	printf("Enter your grade in capital letter. __\b\b");
	scanf("%c", &grade);
	comment(grade);
	return 0;
}

void comment(char ch) {
	switch (ch) {
	case 'A':
		printf("Exellent.\n");
		break;
	case 'B':
		printf("Good.\n");
		break;
	case 'C':
		printf("Not Bad.\n");
		break;
	case 'D':
		printf("Need effort.\n");
		break;
	case 'F':
		printf("You can do better than this.\n");
		break;
	default:
		printf("No such grade.\n");
		break;
	}
	return;
}

그런데 한가지 주의할 점은 switch조건문은 알맞은 case를 만난 뒤 그 이후에 나오는 case들은 조건과 관계없이 모두 실행된다는 것 입니다. 이를 방지하기 위해 루프문을 빠져나가도록 생긴 명령어가 break;입니다.

Break문 

뒤에서 후술할 반복 구조를 가진 명령문 또는 switch의 case가 여러개 실행되는 것을 방지하기 위해 생긴 명령문입니다. 코드에서 break를 만나면 즉시 함수 또는 루프에서 빠져나가 상위 영역(Scope)에 존재하는 다음 함수 또는 명령어를 실행합니다.

Default:에서는 case에 해당하지 않는 이외의 조건들일때 실행됩니다. else와 역할이 비슷하다 생각하면 되겠습니다.

※ 영역(Scope)에 대한 내용은 다음(Chapter8 함수2)에 다루겠습니다.

//모든 예제 소스는 한빛 미디어홈페이지에서 찾으실 수 있습니다.

IT CookBook, 전공자를 위한 C 언어 프로그래밍 (hanbit.co.kr)

또는 cyphen156/Work-space: Studying (github.com)에서 찾으실 수 있습니다.

 

 

 

 

 

'프로그래밍 > C언어' 카테고리의 다른 글

Chapter6 반복문 : for와 while  (0) 2023.07.12
Chapter5 과제  (0) 2023.06.21
Chapter4 과제  (0) 2023.02.10
Chapter4 함수Ⅰ  (0) 2023.02.09
Chapter3 과제  (0) 2023.02.03