260929 정리 - 조건문 / 반복문

강현구
∙∙조회 8

조건문

주어진 조건의 참(true) 또는 거짓(false) 여부에 따라 프로그램의 실행 흐름을 나누는 구문

 


bool 변수를 그대로 조건으로 쓰기

비교 결과를 담은 bool 변수는 그대로 조건이 됨.

== true 를 붙일 필요가 없음.

charp
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 줄이 읽기 쉬워짐

charp
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("문을 열 수 있음");
}

실행 결과

plain text
문을 열 수 있음
문을 열 수 있음

 


중괄호의 생략

생략하면 if 에 딸린 문장은 바로 다음 한 줄뿐임.
나중에 한 줄을 더 넣으면 그 줄은 조건과 무관하게 항상 실행됨.

csharp
using System;

int hp = 50;

if (hp <= 0)
    Console.WriteLine("쓰러졌음");
    Console.WriteLine("부활 대기 중");   // if 에 딸리지 않음

Console.WriteLine("--- 끝 ---");

실행 결과

diff
부활 대기 중
--- 끝 ---

들여쓰기가 맞춰져 있어서 두 줄 모두 if에 속한 것처럼 보이지만, 실제로는 두 번째 줄이 조건과 무관하게 실행됨. 중괄호를 쓰면 이런 일이 생기지 않음.

 


짝수와 홀수

정수를 2로 나눈 나머지가 0이면 짝수이고, 0이 아니면 홀수임.

음수 홀수의 나머지는 -1이므로 1과 같은지만 검사하면 안 됨.

csharp
using System;

int number = 15;

if (number % 2 == 0)
{
    Console.WriteLine($"{number} 은 짝수");
}
else
{
    Console.WriteLine($"{number} 은 홀수");
}

실행 결과

plain text
15 은 홀수

여러 수를 확인하면 나머지가 어떻게 갈리는지 보임.

csharp
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 ? "짝수" : "홀수")}");

실행 결과

ini
8 % 2 = 0 → 짝수
13 % 2 = 1 → 홀수
0 % 2 = 0 → 짝수
-7 % 2 = -1 → 홀수

음수는 나머지가 -1이 되므로 % 2 == 1로 홀수를 판정하면 음수에서 틀림. 짝수를 == 0으로 판정하고 나머지를 else로 처리하는 것이 안전함.

csharp
using System;

int d = -7;

Console.WriteLine($"% 2 == 1 로 홀수 판정: {d % 2 == 1}");   // 음수에서 틀림
Console.WriteLine($"% 2 != 0 로 홀수 판정: {d % 2 != 0}");   // 음수에서도 맞음

실행 결과

ini
% 2 == 1 로 홀수 판정: False
% 2 != 0 로 홀수 판정: True

 


if else 의 분기

핵심은 위에서부터 차례로 검사하고, 처음 참이 된 것 하나만 실행한 뒤 나머지를 건너뛴다는 점임.

csharp
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를 넣을 수 있음. 앞 조건이 참인 경우에만 다음 조건을 따져야 할 때 씀.

csharp
using System;

string id = "player1";
string password = "1234";

if (id == "player1")
{
    Console.WriteLine("아이디 확인");

    if (password == "1234")
    {
        Console.WriteLine("로그인 성공");
    }
    else
    {
        Console.WriteLine("비밀번호가 틀림");
    }
}
else
{
    Console.WriteLine("없는 아이디");
}

실행 결과

plain text
아이디 확인
로그인 성공

바깥 조건이 거짓이면 안쪽은 아예 검사되지 않음. 위 예제에서 아이디가 틀리면 비밀번호는 확인하지 않고 “없는 아이디”만 나옴.

csharp
using System;

string id = "guest";
string password = "1234";

if (id == "player1")
{
    Console.WriteLine("아이디 확인");

    if (password == "1234")
    {
        Console.WriteLine("로그인 성공");
    }
    else
    {
        Console.WriteLine("비밀번호가 틀림");
    }
}
else
{
    Console.WriteLine("없는 아이디");
}

실행 결과

plain text
없는 아이디

중첩 대신 && 로 묶기

갈래마다 다른 처리가 필요하지 않고 모두 참일 때만 실행하면 되는 경우라면, 중첩하지 않고 &&로 묶는 것이 짧고 읽기 쉬움.

csharp
using System;

int level = 12;
int stamina = 5;

// 중첩
if (level >= 10)
{
    if (stamina > 0)
    {
        Console.WriteLine("던전에 들어감");
    }
}

// 중첩 대신 && 로 묶기
if (level >= 10 && stamina > 0)
{
    Console.WriteLine("던전에 들어감");
}

실행 결과

plain text
던전에 들어감
던전에 들어감

어느 쪽을 쓸 것인가

상황형태
모든 조건이 참일 때만 실행하고, 실패 이유를 구분하지 않음&&로 묶음
어느 조건에서 실패했는지에 따라 다른 처리가 필요함중첩 if
조건이 셋 이상 겹쳐 들여쓰기가 깊어짐&&로 묶거나 조건을 bool 변수로 뽑음
csharp
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("던전에 들어감");
}

실행 결과

plain text
레벨이 낮음

들어가지 못하는 조건을 먼저 걸러 내고 마지막 else에서 통과 처리를 하는 형태임. 중첩을 깊게 만들지 않으면서 실패 이유를 구분할 수 있음.

 


switch 문

값이 무엇인지로 갈라내기

if는 조건식이 참인지를 보지만,

switch는 하나의 값이 무엇인지를 보고 갈라냄. 같은 변수를 여러 값과 비교할 때

else if를 늘어놓는 것보다 짧고 의도가 분명함.

arduino
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에는 ;

 

csharp
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;
}

실행 결과

plain text
저장된 게임을 불러옴

 

case 에 변수를 쓸 수 없음

case 뒤에 적는 값은 컴파일 시점에 정해지는 상수여야 함. 변수는 쓸 수 없음.

 

default

default는 어느 case에도 맞지 않을 때 실행됨.

csharp
using System;

int menu = 9;

switch (menu)
{
    case 1:
        Console.WriteLine("새 게임");
        break;
    case 2:
        Console.WriteLine("이어하기");
        break;
    default:
        Console.WriteLine($"{menu} 번은 없는 메뉴임");
        break;
}

실행 결과

plain text
9 번은 없는 메뉴임
  • if문의 else 처럼 default를 생략하면 맞는 case가 없을 때 아무것도 실행되지 않음.

 

여러 case 를 묶기

같은 처리를 해야 하는 값들은 case를 연달아 적어 묶음. 이때는 사이에

break를 넣지 않음.

csharp
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;
}

실행 결과

plain text
주말

case 6:과 case 7:이 같은 블록을 공유함. 실행할 코드가 없는 case를 나열하는 것은 허용되고, 코드가 있는 case에서 break 없이 다음으로 내려가는 것은 허용되지 않음.

 

 

문자열로 갈라내기

switch는 문자열에도 쓸 수 있음. 대소문자는 구분됨.

csharp
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;
}

실행 결과

plain text
공격함

 

문자로 갈라내기

csharp
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);

실행 결과

makefile
녹색: 진행
  • 각 case에서 변수에 값만 넣고, 출력은 switch 밖에서 한 번만 함.
  • Console.WriteLine을 case마다 반복하지 않아 고칠 곳이 줄어듦.

 


switch 에 알맞은 타입

타입switch 로 갈라내기
int, long, short, byte 등 정수알맞음
char알맞음
string알맞음
bool알맞음
float, double, decimal문법은 되지만 쓰지 않음

 


 

_ 는 나머지 전부

switch 식에서 _는 switch 문의 default에 해당함.

csharp
using System;

string grade = "S";

int reward = grade switch
{
    "S" => 1000,
    "A" => 500,
    "B" => 200,
    _ => 0
};

Console.WriteLine($"{grade} 등급 보상: {reward}");

실행 결과

yaml
S 등급 보상: 1000

 

반드시 값이 나와야 함

switch 식은 값을 만들어 내는 식이므로, 어떤 값이 들어와도 결과가 하나 정해져야 함. _를 빼면 맞는 것이 없을 때 값을 만들 수 없어 오류가 남.

csharp
using System;

int day = 9;

string name = day switch
{
    1 => "월요일",
    2 => "화요일",
    _ => "잘못된 요일 번호"
};

Console.WriteLine(name);

실행 결과

plain text
잘못된 요일 번호

_를 빼고 맞지 않는 값을 넣으면 실행 중에 오류가 남.

csharp
using System;

int day = 9;

string name = day switch
{
    1 => "월요일",
    2 => "화요일"
};

Console.WriteLine(name);

실행 결과

less
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 { 대상 => 결과, ... } 형태
  • _가 나머지 전부를 받음. 어떤 값이 와도 결과가 정해져야 함
  • 모든 갈래의 결과 타입이 맞아야 함

핵심 코드 요약

csharp
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는 반복에 필요한 세 가지를 괄호 안에 모아 적음.

scss
for (초기식; 조건식; 증감식)
{
    // 반복할 코드
}

부분언제 실행되는가하는 일
초기식반복 시작 전 한 번만반복 변수를 만들고 시작값을 넣음
조건식매 반복 직전참이면 본문 실행, 거짓이면 반복 종료
증감식매 반복 직후반복 변수를 바꿈

세 부분은 세미콜론으로 구분함. 마지막 증감식 뒤에는 세미콜론을 붙이지 않음.

 

 


while 문

조건이 참인 동안

  • while 은 조건식만 괄호에 적음. 초기식과 증감식은 밖에 둠.
csharp
using System;

int count = 0;

while (count < 3)
{
    Console.WriteLine("안녕하세요.");
    count++;
}

실행 결과

plain text
안녕하세요.
안녕하세요.
안녕하세요.