260929 정리 - 조건문 / 반복문
조건문
주어진 조건의 참(true) 또는 거짓(false) 여부에 따라 프로그램의 실행 흐름을 나누는 구문
bool 변수를 그대로 조건으로 쓰기
비교 결과를 담은 bool 변수는 그대로 조건이 됨.
== true 를 붙일 필요가 없음.
using System;
int hp = 80;
int mp = 40;
bool canCast = hp > 0 && mp >= 30;
if (canCast)
{
Console.WriteLine("주문을 시전함");
}
if (!canCast)
{
Console.WriteLine("주문을 쓸 수 없음");
}
- 즉 변수 자체가 bool 형이면 변수만 넣어도 인정
미리 뽑아두기
조건이 복잡할 때는 이렇게 이름 있는
bool 변수로 뽑아 두면
if 줄이 읽기 쉬워짐
using System;
int level = 12;
int stamina = 5;
bool hasKey = true;
// 조건을 그대로 늘어놓으면
if (level >= 10 && stamina > 0 && hasKey)
{
Console.WriteLine("문을 열 수 있음");
}
// 이름을 붙이면
bool isStrongEnough = level >= 10;
bool canMove = stamina > 0;
bool canOpenDoor = isStrongEnough && canMove && hasKey;
if (canOpenDoor)
{
Console.WriteLine("문을 열 수 있음");
}
실행 결과
문을 열 수 있음
문을 열 수 있음
중괄호의 생략
생략하면 if 에 딸린 문장은 바로 다음 한 줄뿐임.
나중에 한 줄을 더 넣으면 그 줄은 조건과 무관하게 항상 실행됨.
using System;
int hp = 50;
if (hp <= 0)
Console.WriteLine("쓰러졌음");
Console.WriteLine("부활 대기 중"); // if 에 딸리지 않음
Console.WriteLine("--- 끝 ---");
실행 결과
부활 대기 중
--- 끝 ---
들여쓰기가 맞춰져 있어서 두 줄 모두 if에 속한 것처럼 보이지만, 실제로는 두 번째 줄이 조건과 무관하게 실행됨. 중괄호를 쓰면 이런 일이 생기지 않음.
짝수와 홀수
정수를 2로 나눈 나머지가 0이면 짝수이고, 0이 아니면 홀수임.
음수 홀수의 나머지는 -1이므로 1과 같은지만 검사하면 안 됨.
using System;
int number = 15;
if (number % 2 == 0)
{
Console.WriteLine($"{number} 은 짝수");
}
else
{
Console.WriteLine($"{number} 은 홀수");
}
실행 결과
15 은 홀수
여러 수를 확인하면 나머지가 어떻게 갈리는지 보임.
using System;
int a = 8;
int b = 13;
int c = 0;
int d = -7;
Console.WriteLine($"{a} % 2 = {a % 2} → {(a % 2 == 0 ? "짝수" : "홀수")}");
Console.WriteLine($"{b} % 2 = {b % 2} → {(b % 2 == 0 ? "짝수" : "홀수")}");
Console.WriteLine($"{c} % 2 = {c % 2} → {(c % 2 == 0 ? "짝수" : "홀수")}");
Console.WriteLine($"{d} % 2 = {d % 2} → {(d % 2 == 0 ? "짝수" : "홀수")}");
실행 결과
8 % 2 = 0 → 짝수
13 % 2 = 1 → 홀수
0 % 2 = 0 → 짝수
-7 % 2 = -1 → 홀수
음수는 나머지가 -1이 되므로 % 2 == 1로 홀수를 판정하면 음수에서 틀림. 짝수를 == 0으로 판정하고 나머지를 else로 처리하는 것이 안전함.
using System;
int d = -7;
Console.WriteLine($"% 2 == 1 로 홀수 판정: {d % 2 == 1}"); // 음수에서 틀림
Console.WriteLine($"% 2 != 0 로 홀수 판정: {d % 2 != 0}"); // 음수에서도 맞음
실행 결과
% 2 == 1 로 홀수 판정: False
% 2 != 0 로 홀수 판정: True
if else 의 분기
핵심은 위에서부터 차례로 검사하고, 처음 참이 된 것 하나만 실행한 뒤 나머지를 건너뛴다는 점임.
using System;
int percent = 45;
if (percent >= 75)
{
Console.WriteLine("상태: 안전");
}
else if (percent >= 50)
{
Console.WriteLine("상태: 보통");
}
else if (percent >= 25)
{
Console.WriteLine("상태: 위험");
}
else
{
Console.WriteLine("상태: 치명");
}
- 중간에 참이 되는 부분이 있다면 그 부분 뒤에 있는걸 모두 건너뜀
중첩 if
if 안에 if
if블록 안에 다시 if 를 넣을 수 있음. 앞 조건이 참인 경우에만 다음 조건을 따져야 할 때 씀.
if 블록 안에 다시 if를 넣을 수 있음. 앞 조건이 참인 경우에만 다음 조건을 따져야 할 때 씀.
using System;
string id = "player1";
string password = "1234";
if (id == "player1")
{
Console.WriteLine("아이디 확인");
if (password == "1234")
{
Console.WriteLine("로그인 성공");
}
else
{
Console.WriteLine("비밀번호가 틀림");
}
}
else
{
Console.WriteLine("없는 아이디");
}
실행 결과
아이디 확인
로그인 성공
바깥 조건이 거짓이면 안쪽은 아예 검사되지 않음. 위 예제에서 아이디가 틀리면 비밀번호는 확인하지 않고 “없는 아이디”만 나옴.
using System;
string id = "guest";
string password = "1234";
if (id == "player1")
{
Console.WriteLine("아이디 확인");
if (password == "1234")
{
Console.WriteLine("로그인 성공");
}
else
{
Console.WriteLine("비밀번호가 틀림");
}
}
else
{
Console.WriteLine("없는 아이디");
}
실행 결과
없는 아이디
중첩 대신 && 로 묶기
갈래마다 다른 처리가 필요하지 않고 모두 참일 때만 실행하면 되는 경우라면, 중첩하지 않고 &&로 묶는 것이 짧고 읽기 쉬움.
using System;
int level = 12;
int stamina = 5;
// 중첩
if (level >= 10)
{
if (stamina > 0)
{
Console.WriteLine("던전에 들어감");
}
}
// 중첩 대신 && 로 묶기
if (level >= 10 && stamina > 0)
{
Console.WriteLine("던전에 들어감");
}
실행 결과
던전에 들어감
던전에 들어감
어느 쪽을 쓸 것인가
| 상황 | 형태 |
|---|---|
| 모든 조건이 참일 때만 실행하고, 실패 이유를 구분하지 않음 | &&로 묶음 |
| 어느 조건에서 실패했는지에 따라 다른 처리가 필요함 | 중첩 if |
| 조건이 셋 이상 겹쳐 들여쓰기가 깊어짐 | &&로 묶거나 조건을 bool 변수로 뽑음 |
using System;
int level = 8;
int stamina = 0;
bool hasTicket = false;
// 실패 이유를 알려 줘야 하므로 갈래마다 처리를 둠
if (level < 10)
{
Console.WriteLine("레벨이 낮음");
}
else if (stamina <= 0)
{
Console.WriteLine("행동력이 없음");
}
else if (!hasTicket)
{
Console.WriteLine("입장권이 없음");
}
else
{
Console.WriteLine("던전에 들어감");
}
실행 결과
레벨이 낮음
들어가지 못하는 조건을 먼저 걸러 내고 마지막 else에서 통과 처리를 하는 형태임. 중첩을 깊게 만들지 않으면서 실패 이유를 구분할 수 있음.
switch 문
값이 무엇인지로 갈라내기
if는 조건식이 참인지를 보지만,
switch는 하나의 값이 무엇인지를 보고 갈라냄. 같은 변수를 여러 값과 비교할 때
else if를 늘어놓는 것보다 짧고 의도가 분명함.
switch (검사할 값) //즉 변수
{
case 값1:
// 값1일 때
break;
case 값2:
// 값2일 때
break;
default:
// 어느 case 에도 맞지 않을 때
break;
}
| 부분 | 설명 |
|---|---|
switch (값) | 비교할 값. 변수나 식을 넣음 |
case 값: | 비교 대상. 콜론으로 끝남 |
break; | 이 case 처리를 끝내고 switch를 벗어남 |
default: | 어느 case에도 맞지 않을 때. 생략 가능 |
- default - 이거 넣어도 되고 없어도 됨 마치 if문의 else같은거
- case옆에 상수가 붙어야함
- case 옆에는 :
- 그외 다른 조건이나 break에는 ;
using System;
int menu = 2;
switch (menu)
{
case 1:
Console.WriteLine("새 게임을 시작함");
break;
case 2:
Console.WriteLine("저장된 게임을 불러옴");
break;
case 3:
Console.WriteLine("게임을 종료함");
break;
default:
Console.WriteLine("없는 메뉴 번호");
break;
}
실행 결과
저장된 게임을 불러옴
case 에 변수를 쓸 수 없음
case 뒤에 적는 값은 컴파일 시점에 정해지는 상수여야 함. 변수는 쓸 수 없음.
default
default는 어느 case에도 맞지 않을 때 실행됨.
using System;
int menu = 9;
switch (menu)
{
case 1:
Console.WriteLine("새 게임");
break;
case 2:
Console.WriteLine("이어하기");
break;
default:
Console.WriteLine($"{menu} 번은 없는 메뉴임");
break;
}
실행 결과
9 번은 없는 메뉴임
- if문의 else 처럼 default를 생략하면 맞는 case가 없을 때 아무것도 실행되지 않음.
여러 case 를 묶기
같은 처리를 해야 하는 값들은 case를 연달아 적어 묶음. 이때는 사이에
break를 넣지 않음.
using System;
int day = 6;
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
Console.WriteLine("평일");
break;
case 6:
case 7:
Console.WriteLine("주말");
break;
default:
Console.WriteLine("잘못된 요일 번호");
break;
}
실행 결과
주말
case 6:과 case 7:이 같은 블록을 공유함. 실행할 코드가 없는 case를 나열하는 것은 허용되고, 코드가 있는 case에서 break 없이 다음으로 내려가는 것은 허용되지 않음.
문자열로 갈라내기
switch는 문자열에도 쓸 수 있음. 대소문자는 구분됨.
using System;
string command = "attack";
switch (command)
{
case "attack":
Console.WriteLine("공격함");
break;
case "defend":
Console.WriteLine("방어함");
break;
case "run":
Console.WriteLine("도망침");
break;
default:
Console.WriteLine($"'{command}' 는 알 수 없는 명령임");
break;
}
실행 결과
공격함
문자로 갈라내기
using System;
char signal = 'G';
string message;
switch (signal)
{
case 'R':
message = "적색: 멈춤";
break;
case 'Y':
message = "황색: 주의";
break;
case 'G':
message = "녹색: 진행";
break;
default:
message = "신호 없음";
break;
}
Console.WriteLine(message);
실행 결과
녹색: 진행
- 각
case에서 변수에 값만 넣고, 출력은switch밖에서 한 번만 함. Console.WriteLine을case마다 반복하지 않아 고칠 곳이 줄어듦.
switch 에 알맞은 타입
| 타입 | switch 로 갈라내기 |
|---|---|
int, long, short, byte 등 정수 | 알맞음 |
char | 알맞음 |
string | 알맞음 |
bool | 알맞음 |
float, double, decimal | 문법은 되지만 쓰지 않음 |
_ 는 나머지 전부
switch식에서_는switch문의default에 해당함.
using System;
string grade = "S";
int reward = grade switch
{
"S" => 1000,
"A" => 500,
"B" => 200,
_ => 0
};
Console.WriteLine($"{grade} 등급 보상: {reward}");
실행 결과
S 등급 보상: 1000
반드시 값이 나와야 함
switch식은 값을 만들어 내는 식이므로, 어떤 값이 들어와도 결과가 하나 정해져야 함._를 빼면 맞는 것이 없을 때 값을 만들 수 없어 오류가 남.
using System;
int day = 9;
string name = day switch
{
1 => "월요일",
2 => "화요일",
_ => "잘못된 요일 번호"
};
Console.WriteLine(name);
실행 결과
잘못된 요일 번호
_를 빼고 맞지 않는 값을 넣으면 실행 중에 오류가 남.
using System;
int day = 9;
string name = day switch
{
1 => "월요일",
2 => "화요일"
};
Console.WriteLine(name);
실행 결과
Unhandled exception. System.Runtime.CompilerServices.SwitchExpressionException: Non-exhaustive switch expression failed to match its input.
Unmatched value was 9.
마지막 줄 아래로 오류가 난 자리까지의 호출 경로가 함께 찍힘.
컴파일할 때 “모든 경우를 다루지 않았음”이라는 경고도 함께 나옴. switch 식에는 _를 두는 것이 원칙임.
정리
제어문
- 순차·조건·반복 세 갈래로 나뉨. 조건문은
if와switch - 조건문이 없으면 코드는 위에서 아래로 빠짐없이 실행됨
if 문
- 조건식이 참일 때만 중괄호 안을 실행함
- 조건식은 반드시
bool이어야 함. 숫자를 조건으로 쓸 수 없음 bool변수는== true없이 그대로 조건으로 씀- 실행할 문장이 한 줄이어도 중괄호를 씀
if (조건);처럼 세미콜론을 붙이면 조건이 무의미해짐
else · else if
else는 조건이 거짓일 때 실행됨. 조건을 적지 않음else if는 위에서부터 검사해 처음 참이 된 하나만 실행함- 그러므로 범위가 좁은 조건을 먼저 두어야 함
- 앞 조건이 걸러 준 범위를 다시 적지 않아도 됨
- 여러 조건이 동시에 참일 수 있고 그것을 모두 알려야 하면
else로 잇지 않고if를 따로 놓음
중첩 if
- 앞 조건이 참일 때만 다음을 따져야 하면 중첩함
- 실패 이유를 구분하지 않으면
&&로 펴는 것이 읽기 쉬움 - 들여쓰기가 깊어지면 조건을
bool변수로 뽑거나 실패 조건을 먼저 걸러 냄
switch 문
- 하나의 값이 무엇인지로 갈라냄.
case에 적는 값은 상수여야 하고 변수는 올 수 없음 - 실행 본문이 있는
case구간은 다음 구간으로 흘러내리지 않도록break등으로 끝냄. 빈case레이블은 연달아 묶을 수 있음 - 같은 처리를 할 값들은
case를 연달아 적어 묶음 - 정수·
char·string·bool로 갈라내는 데 알맞음. 실수는 문법상 되지만 값이 어긋나기 쉬워 쓰지 않음 case에 값을 하나씩 적는 방식으로는 범위를 적을 수 없으므로 범위는else if로 갈라냄
switch 식
- 값을 고르는 식임.
값 switch { 대상 => 결과, ... }형태 _가 나머지 전부를 받음. 어떤 값이 와도 결과가 정해져야 함- 모든 갈래의 결과 타입이 맞아야 함
핵심 코드 요약
using System;
int hp = 45;
// if · else if · else — 범위로 갈라냄
if (hp <= 0)
{
Console.WriteLine("사망");
}
else if (hp < 30)
{
Console.WriteLine("위험");
}
else
{
Console.WriteLine("정상");
}
// switch 문 — 값으로 갈라내고 여러 문장을 실행함
string command = "attack";
switch (command)
{
case "attack":
Console.WriteLine("공격");
break;
case "defend":
Console.WriteLine("방어");
break;
default:
Console.WriteLine("알 수 없는 명령");
break;
}
// switch 식 — 값을 골라 담음
string grade = "A";
int gold = grade switch
{
"S" => 1000,
"A" => 500,
"B" => 300,
_ => 100
};
Console.WriteLine($"보상 {gold} 골드");
반복문
같은 코드를 여러 번 실행하게 만드는 문장
for문
for는 반복에 필요한 세 가지를 괄호 안에 모아 적음.
for (초기식; 조건식; 증감식)
{
// 반복할 코드
}
| 부분 | 언제 실행되는가 | 하는 일 |
|---|---|---|
| 초기식 | 반복 시작 전 한 번만 | 반복 변수를 만들고 시작값을 넣음 |
| 조건식 | 매 반복 직전 | 참이면 본문 실행, 거짓이면 반복 종료 |
| 증감식 | 매 반복 직후 | 반복 변수를 바꿈 |
세 부분은 세미콜론으로 구분함. 마지막 증감식 뒤에는 세미콜론을 붙이지 않음.
while 문
조건이 참인 동안
- while 은 조건식만 괄호에 적음. 초기식과 증감식은 밖에 둠.
using System;
int count = 0;
while (count < 3)
{
Console.WriteLine("안녕하세요.");
count++;
}
실행 결과
안녕하세요.
안녕하세요.
안녕하세요.



