C 제어문 마스터: if, switch, 조건 연산자로 결정 로직 구현하기
프로그램의 흐름을 제어하는 결정 구조를 다룹니다. C에서 참/거짓 판단 기준과 각 제어문의 문법, 중첩, 모범 사례를 정리합니다.
C에서 참과 거짓
거짓(0): 정수 0, 널 포인터 NULL, \0
참(참): 0이 아닌 모든 값 (음수 포함), 유효 포인터
관계/논리 연산 결과: 참=1, 거짓=0 (int 타입)
<stdbool.h> (C99): bool, true(1), false(0) 매크로 제공
if 문
기본 형태
if (조건)
문장; // 단일 문장 (중괄호 생략 가능)
if (조건) {
문장1;
문장2; // 복합 문장 (블록) - 권장
}
if-else 문
if (score >= 60)
printf("합격\n");
else
printf("불합격\n");
if-else if-else 연쇄
if (score >= 90)
grade = 'A';
else if (score >= 80)
grade = 'B';
else if (score >= 70)
grade = 'C';
else if (score >= 60)
grade = 'D';
else
grade = 'F';
중첩 if
if (age >= 18) {
if (has_license)
printf("운전 가능\n");
else
printf("면허 필요\n");
} else {
printf("미성년자\n");
}
switch 문
정수/문자/열거형 값을 여러 상수와 비교할 때 효율적.
문법
switch (표현식) {
case 상수1:
문장들;
break; // 없으면 fall-through 발생
case 상수2:
case 상수3: // 여러 case 공유 가능
문장들;
break;
default: // 선택 사항, 매칭 없을 때
문장들;
}
예제: 메뉴 처리
int menu;
scanf("%d", &menu);
switch (menu) {
case 1: printf("조회\n"); break;
case 2: printf("등록\n"); break;
case 3: printf("수정\n"); break;
case 4: printf("삭제\n"); break;
case 0: printf("종료\n"); break;
default: printf("잘못된 메뉴\n");
}
switch 제약사항
case 레이블은 정수 상수 표현식만 가능 (변수, 범위, 실수 불가)
case 중복 불가
break 생략 시 다음 case로 낙하 (fall-through) - 의도적일 때만 주석으로 명시
조건 연산자 (삼항 연산자) ? :
조건 ? 참_표현식 : 거짓_표현식
특징
표현식이므로 값 산출, 대입/인자/반환에 사용 가능
단락 평가: 조건 참이면 참_표현식만, 거짓이면 거짓_표현식만 평가
두 표현식 타입 호환되어야 함 (공통 타입으로 변환)
활용 예
// 최댓값
int max = (a > b) ? a : b;
// 절댓값
int abs = (x >= 0) ? x : -x;
// 안전한 나눗셈
double result = (denom != 0) ? (num / denom) : 0.0;
// 포인터 기본값
const char *name = (ptr != NULL) ? ptr->name : "Unknown";
// 중첩 (가독성 나빠질 수 있음)
int sign = (x > 0) ? 1 : (x < 0) ? -1 : 0;
다중 선택 패턴 비교
| 상황 | 추천 | 이유 |
| 단순 참/거짓 | if-else | 가독성 좋음 |
| 단일 값 다중 분기 (정수/문자) | switch | 점프 테이블 최적화 가능, 가독성 |
| 범위 비교, 복합 조건 | if-else if | switch 불가 |
| 단순 값 선택/대입 | ? : | 간결, 표현식 문맥 활용 |
| 불리언 플래그 설정 | flag = (cond) | 조건 연산자 불필요 |
자주 하는 실수
if (x = 10) 대입을 비교로 착각 → if (x == 10) 또는 if (10 == x) (상수 왼쪽)
switch에서 break 누락 → 의도치 않은 fall-through
부동소수점 비교: if (f == 1.0) 위험 → fabs(f - 1.0) < EPSILON
문자열 비교: if (str == "abc") 주소 비교 → strcmp(str, "abc") == 0
컴파일러 최적화 힌트
switch case 값이 조밀하면 점프 테이블 생성 (O(1))
if-else if는 순차 평가 (O(n)), 자주 참인 조건을 위로
likely()/unlikely() 매크로(GCC/Clang)로 분기 예측 힌트 제공 가능