260929 정리 - 조건문 / 반복문
댓글 0
댓글을 작성하려면 로그인이 필요합니다.
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요.
댓글을 작성하려면 로그인이 필요합니다.
아직 댓글이 없습니다. 첫 번째 댓글을 작성해보세요.
주어진 조건의 참(true) 또는 거짓(false) 여부에 따라 프로그램의 실행 흐름을 나누는 구문
비교 결과를 담은 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 변수로 뽑아 두면
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
핵심은 위에서부터 차례로 검사하고, 처음 참이 된 것 하나만 실행한 뒤 나머지를 건너뛴다는 점임.
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를 넣을 수 있음. 앞 조건이 참인 경우에만 다음 조건을 따져야 할 때 씀.
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에서 통과 처리를 하는 형태임. 중첩을 깊게 만들지 않으면서 실패 이유를 구분할 수 있음.
if는 조건식이 참인지를 보지만,
switch는 하나의 값이 무엇인지를 보고 갈라냄. 같은 변수를 여러 값과 비교할 때
else if를 늘어놓는 것보다 짧고 의도가 분명함.
switch (검사할 값) //즉 변수
{
case 값1:
// 값1일 때
break;
case 값2:
// 값2일 때
break;
default:
// 어느 case 에도 맞지 않을 때
break;
}
| 부분 | 설명 |
|---|---|
switch (값) | 비교할 값. 변수나 식을 넣음 |
case 값: | 비교 대상. 콜론으로 끝남 |
break; | 이 case 처리를 끝내고 switch를 벗어남 |
default: | 어느 case에도 맞지 않을 때. 생략 가능 |
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 뒤에 적는 값은 컴파일 시점에 정해지는 상수여야 함. 변수는 쓸 수 없음.
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 번은 없는 메뉴임
같은 처리를 해야 하는 값들은 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 로 갈라내기 |
|---|---|
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와 switchif 문
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 (초기식; 조건식; 증감식)
{
// 반복할 코드
}
| 부분 | 언제 실행되는가 | 하는 일 |
|---|---|---|
| 초기식 | 반복 시작 전 한 번만 | 반복 변수를 만들고 시작값을 넣음 |
| 조건식 | 매 반복 직전 | 참이면 본문 실행, 거짓이면 반복 종료 |
| 증감식 | 매 반복 직후 | 반복 변수를 바꿈 |
세 부분은 세미콜론으로 구분함. 마지막 증감식 뒤에는 세미콜론을 붙이지 않음.
조건이 참인 동안
using System;
int count = 0;
while (count < 3)
{
Console.WriteLine("안녕하세요.");
count++;
}
실행 결과
안녕하세요.
안녕하세요.
안녕하세요.
Develog는 단순히 글을 쓰는 공간이 아닙니다. 성장의 과정을 기록하고, 그 기록으로 나를 증명하며 원하는 기회를 얻는 곳이길 바랐습니다. 누군가의 꿈으로 향하는 중간다리가 되는 것, 그것이 Develog를 만든 이유입니다.

우리들의 게임 발매 이야기

안녕하세요. 플밍 4기 입니다. 게임 개발을 배우기 전 네트워크 엔지니어 도메인에서 익히고 배웠던 네트워크 이론에 대한 기초 입니다. 학습에 도움이 되길 바라며 공유 드립니다.
Develog는 단순히 글을 쓰는 공간이 아닙니다. 성장의 과정을 기록하고, 그 기록으로 나를 증명하며 원하는 기회를 얻는 곳이길 바랐습니다. 누군가의 꿈으로 향하는 중간다리가 되는 것, 그것이 Develog를 만든 이유입니다.



안녕하세요. 플밍 4기 입니다. 게임 개발을 배우기 전 네트워크 엔지니어 도메인에서 익히고 배웠던 네트워크 이론에 대한 기초 입니다. 학습에 도움이 되길 바라며 공유 드립니다.