표현식과 흐름 제어
표현식과 흐름 제어
1. 전체 학습 흐름
자료형 변환
↓
조건식의 true / false
↓
if·switch로 선택
↓
while·for로 반복
↓
break·continue로 반복 제어| 구분 | 문법 | 역할 |
|---|---|---|
| 선택 | if, if else, switch | 조건에 따라 실행할 코드 선택 |
| 반복 | while, do while, for | 조건을 만족하는 동안 코드 반복 |
2. 자료형 변환
서로 다른 자료형을 함께 계산하면 C++가 계산에 사용할 공통 자료형을 결정합니다.
int a = 5;
double b = 2.5;
auto c = a + b;위 계산에서는 a가 double로 변환됩니다.
int 5 + double 2.5
↓
double 5.0 + double 2.5
↓
double 7.5| 표현식 | 처리 | 결과 |
|---|---|---|
3 + 4.5 | 3을 double로 변환 | double 7.5 |
7 / 2 | 두 값 모두 int | int 3 |
7 / 2.0 | 7을 double로 변환 | double 3.5 |
static_cast<double>(7) / 2 | 7을 명시적으로 변환 | double 3.5 |
정수 승격
bool, char, short처럼 작은 정수형은 산술 계산에서 일반적으로 int로 승격됩니다.
bool / char / short
↓
int축소 변환
더 넓은 자료형의 값을 더 좁은 자료형으로 바꾸면 데이터가 손실될 수 있습니다.
double pi = 3.14;
int number = pi;3.14
↓ 소수 부분 손실
3uint16_t x = 10000;
uint8_t y = x; // uint8_t 범위를 벗어나 데이터 손실 가능중괄호 초기화는 일부 축소 변환을 Compile 단계에서 막아줍니다.
int number{3.14}; // Compile Error핵심: 혼합 자료형을 계산할 때는 각 피연산자와 최종 결과의 자료형을 확인합니다.
3. 부동소수점 오차
float와 double은 모든 십진 소수를 정확하게 저장하지 못합니다. 많은 값을 이진수로 표현한 근삿값으로 저장합니다.
#include <iostream>
using namespace std;
int main() {
float sum = 0.0f;
for (int i = 0; i < 1000; i++) {
sum += 0.1f;
}
cout << sum << endl;
return 0;
}0.1을 근삿값으로 저장
↓
1000번 반복해서 덧셈
↓
작은 오차가 누적될 수 있음부동소수점 값은 상황에 따라 아주 작은 허용 오차를 두고 비교합니다.
#include <cmath>
double a = 0.1 + 0.2;
double b = 0.3;
bool same = abs(a - b) < 0.000001;핵심: 부동소수점은 근삿값이므로 계산과 비교에서 오차를 고려해야 합니다.
4. 논리 연산자
| 연산자 | 의미 | 결과가 true인 경우 |
|---|---|---|
A && B | AND | A와 B가 모두 참 |
A || B | OR | A와 B 중 하나 이상이 참 |
!A | NOT | A가 거짓 |
int x = 5;
int y = !x;C++에서 0은 거짓, 0이 아닌 값은 참으로 평가됩니다.
x = 5
5는 0이 아니므로 true
!true는 false
false를 int로 변환하면 0
최종 y = 0주의: 원본 강의자료의
!5가1이라는 설명은 오류입니다. 실제 결과는0입니다.
5. 증감 연산자
x++; // x를 1 증가
x--; // x를 1 감소단독 문장으로 사용하면 다음 코드와 같은 효과입니다.
x = x + 1;
x = x - 1;전위와 후위
| 형식 | 표현식에서의 동작 |
|---|---|
x++ | 현재 값을 먼저 사용한 후 증가 |
++x | 먼저 증가한 후 증가한 값 사용 |
x-- | 현재 값을 먼저 사용한 후 감소 |
--x | 먼저 감소한 후 감소한 값 사용 |
#include <iostream>
using namespace std;
int main() {
int x = 5;
cout << x++ << ' '; // 5 출력 후 x는 6
cout << ++x << endl; // x를 7로 만든 후 7 출력
return 0;
}실행 결과:
5 7피해야 할 코드
한 표현식 안에서 같은 변수를 여러 번 증감하지 않습니다.
int result = x++ + ++x; // 피해야 함증감은 별도 문장으로 분리하는 것이 안전하고 읽기 쉽습니다.
6. 복합 대입 연산자
| 복합 대입 | 같은 의미 |
|---|---|
x += 3 | x = x + 3 |
x -= 3 | x = x - 3 |
x *= 3 | x = x * 3 |
x /= 3 | x = x / 3 |
x %= 3 | x = x % 3 |
int score = 80;
score += 10;최종 결과:
score = 907. 주요 연산자 우선순위
1. ( )
2. ++ --
3. * / %
4. + -
5. < <= > >=
6. == !=
7. &&
8. ||
9. =복잡한 표현식은 우선순위에만 의존하지 말고 괄호를 사용합니다.
bool canEnter = (age >= 18) && hasTicket;8. if
if는 조건이 참일 때만 Block을 실행합니다.
if (condition) {
// condition이 true일 때 실행
}예:
int grade = 95;
if (grade >= 90) {
cout << "A" << endl;
}실행 흐름:
grade >= 90 계산
↓
true인가?
├─ Yes → Block 실행
└─ No → Block 건너뛰기=와 == 구분
if (grade = 100) // 대입: 잘못된 의도
if (grade == 100) // 비교: 올바른 코드grade = 100은 grade에 100을 저장합니다. 대입식의 결과 100은 0이 아니므로 조건이 참으로 평가됩니다.
핵심:
=는 대입이고==는 같은지 비교하는 연산자입니다.
9. if else와 else if
if else는 조건에 따라 두 경로 중 하나를 실행합니다.
if (score >= 60) {
cout << "Pass" << endl;
} else {
cout << "Fail" << endl;
}여러 조건을 순서대로 검사할 때는 else if를 사용합니다.
char letterGrade;
int grade = 85;
if (grade >= 90) {
letterGrade = 'A';
} else if (grade >= 80) {
letterGrade = 'B';
} else if (grade >= 70) {
letterGrade = 'C';
} else {
letterGrade = 'F';
}위에서부터 검사하여 처음 참이 된 분기 하나만 실행합니다. 따라서 더 높은 점수 조건을 먼저 작성해야 합니다.
grade >= 90 ?
├─ true → A
└─ false → grade >= 80 ?
├─ true → B
└─ false → 다음 조건10. switch
switch는 하나의 값을 여러 case와 비교합니다.
switch (expression) {
case value1:
statements;
break;
case value2:
statements;
break;
default:
statements;
}예:
#include <iostream>
using namespace std;
int main() {
int menu = 2;
switch (menu) {
case 1:
cout << "Start" << endl;
break;
case 2:
cout << "Settings" << endl;
break;
default:
cout << "Invalid menu" << endl;
}
return 0;
}실행 결과:
Settingsbreak의 역할
break가 없으면 일치한 case 아래의 다음 case까지 계속 실행될 수 있습니다.
if와 switch
if | switch |
|---|---|
| 범위와 복합 조건에 적합 | 하나의 값과 여러 상수를 비교할 때 적합 |
score >= 90 | menu == 1, menu == 2 |
| 자유로운 조건식 사용 | case에는 상수값 사용 |
11. while
while은 조건을 먼저 확인하고, 참인 동안 Block을 반복합니다.
while (condition) {
statements;
}예:
#include <iostream>
using namespace std;
int main() {
int i = 1;
while (i <= 3) {
cout << i << ' ';
i++;
}
return 0;
}실행 결과:
1 2 3실행 추적:
| 단계 | 조건 | 출력 | 실행 후 i |
|---|---|---|---|
| 시작 | 1 <= 3 → true | 1 | 2 |
| 2회 | 2 <= 3 → true | 2 | 3 |
| 3회 | 3 <= 3 → true | 3 | 4 |
| 종료 | 4 <= 3 → false | 없음 | 4 |
무한 반복 주의
int i = 1;
while (i <= 3) {
cout << i;
// i++가 없으므로 조건이 계속 true
}핵심: 반복문에는 조건을 언젠가 거짓으로 만드는 변화가 필요합니다.
12. do while
do while은 본문을 먼저 실행하고 조건을 검사합니다. 따라서 본문이 최소 한 번 실행됩니다.
do {
statements;
} while (condition);예:
int i = 1;
do {
cout << i << ' ';
i++;
} while (i <= 3);실행 결과:
1 2 3while과 do while
while | do while |
|---|---|
| 조건을 먼저 검사 | 본문을 먼저 실행 |
| 0회 실행 가능 | 최소 1회 실행 |
| 선조건 반복 | 후조건 반복 |
주의:
do while의 마지막에는 세미콜론이 필요합니다.
} while (condition);13. break와 continue
| Keyword | 반복문에서의 역할 |
|---|---|
break | 현재 반복문을 즉시 종료 |
continue | 현재 회차의 남은 코드를 건너뛰고 다음 반복 진행 |
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue;
}
if (i == 5) {
break;
}
cout << i << ' ';
}실행 결과:
1 2 4실행 과정:
i = 1 → 출력
i = 2 → 출력
i = 3 → continue → 출력 생략
i = 4 → 출력
i = 5 → break → 반복 종료주의:
while에서continue를 사용하면 반복 변수의 갱신 코드가 건너뛰어지지 않는지 확인합니다.
14. for
for는 반복 횟수를 제어할 때 주로 사용합니다.
for (initialization; condition; update) {
statements;
}실행 순서:
initialization — 처음 한 번
↓
condition
├─ false → 반복 종료
└─ true
↓
body
↓
update
└────→ condition으로 이동예:
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i < 10; i++) {
cout << i << ' ';
}
return 0;
}실행 결과:
1 2 3 4 5 6 7 8 9본문은 i가 1부터 9일 때 실행되므로 총 9회 실행됩니다.
감소 반복
for (int i = 10; i >= 0; i--) {
cout << i << ' ';
}홀수와 짝수 판별
for (int i = 1; i < 10; i++) {
if (i % 2 == 1) {
cout << i << " is odd" << endl;
} else {
cout << i << " is even" << endl;
}
}i % 2 == 0 → 짝수
i % 2 == 1 → 양의 홀수무한 반복
for의 조건을 생략하면 항상 참으로 처리됩니다.
for (;;) {
// 무한 반복
}종료 조건과 break가 없다면 프로그램이 계속 반복됩니다.
15. 범위 기반 for
범위 기반 for는 Array나 Container의 각 요소를 순서대로 방문합니다.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> numbers = {1, 2, 3, 4};
for (int number : numbers) {
cout << number << ' ';
}
return 0;
}실행 결과:
1 2 3 4일반 for | 범위 기반 for |
|---|---|
| 초기화·조건·갱신을 직접 작성 | 각 요소를 자동으로 순회 |
| Index 또는 횟수 제어에 적합 | 모든 요소를 읽을 때 간결 |
요소를 복사하지 않고 읽기만 할 때는 다음 형식을 사용할 수 있습니다.
for (const int& number : numbers) {
cout << number << ' ';
}16. 반복문 선택 기준
| 상황 | 적합한 반복문 |
|---|---|
| 반복 횟수가 명확함 | for |
| 조건이 참인 동안 반복 | while |
| 본문을 최소 한 번 실행 | do while |
| Container의 모든 요소 순회 | 범위 기반 for |
문법적으로 많은 for와 while을 서로 바꿀 수 있지만, 의도를 가장 명확하게 보여주는 반복문을 선택합니다.
17. 자주 하는 실수
대입과 비교 혼동
if (grade = 100) // 대입
if (grade == 100) // 비교정수 나눗셈 착각
7 / 2 // 3
7 / 2.0 // 3.5반복 변수 갱신 누락
int i = 0;
while (i < 10) {
cout << i;
// i++ 누락 → 무한 반복
}switch에서 break 누락
switch (menu) {
case 1:
cout << "One";
// break가 없으면 다음 case로 진행 가능
case 2:
cout << "Two";
}do while 마지막 세미콜론 누락
do {
// 반복할 코드
} while (condition); // 세미콜론 필요같은 표현식에서 여러 번 증감
int result = i++ + ++i; // 피해야 함각 증감 연산을 별도 문장으로 분리합니다.
최종 핵심
- 혼합 자료형 계산에서는 자동 변환이 발생합니다.
- 축소 변환은 값이나 정밀도를 잃을 수 있습니다.
- 부동소수점은 근삿값이므로 작은 오차가 생길 수 있습니다.
&&,||,!는 조건을 결합하거나 반전합니다.x++는 값을 사용한 후 증가하고++x는 증가한 후 값을 사용합니다.if는 조건,switch는 여러 값 중 하나를 선택할 때 사용합니다.while은 조건을 먼저 검사하고do while은 본문을 먼저 실행합니다.for의 순서는 초기화 → 조건 → 본문 → 갱신입니다.break는 반복을 종료하고continue는 현재 회차를 건너뜁니다.- 범위 기반
for는 Container의 모든 요소를 순회할 때 사용합니다.
내용을 이해했다면 학습 완료를 체크해 주세요.