for 는 적힌 순서대로 실행되지 않는다
앞에서 반복문에는 시작, 계속 조건, 변화 세 가지가 있다고 했습니다.
while 은 이 셋을 세 곳에 흩어 적습니다.
int i = 0; // 시작 (반복문 밖)
while (i < 5) // 계속 조건 (괄호 안)
{
Console.WriteLine(i);
i++; // 변화 (블록 안 맨 아래)
}
세 가지가 멀리 떨어져 있으니 하나를 빠뜨려도 눈에 잘 안 띕니다.
특히 i++ 는 블록 안에 다른 코드와 섞여 있어서, 코드가 길어지면 찾기도 어렵습니다.
셋을 괄호 하나에 모아 적은 것이
for입니다.
for 는 이렇게 생겼다
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
위의 while 코드와 하는 일이 완전히 같습니다.
달라진 것은 세 가지가 한 줄에 모여 있다는 것뿐입니다.
한눈에 보이니 빠뜨리기 어렵습니다.
칸을 나누는 것은 세미콜론입니다. 두 개가 항상 있어야 합니다.
i 라는 이름은 index 의 i 입니다. 관습이라 대부분 이렇게 씁니다.
세 칸은 적힌 순서대로 실행되지 않는다
여기가 이 글의 핵심입니다.
괄호 안에 int i = 0; i < 5; i++ 이 왼쪽부터 나란히 적혀 있으니
그 순서대로 돌 것 같지만, 실제 순서는 다릅니다.
아래에서 for 의 세 칸을 일부러 세 줄로 나눠 적었습니다.
C# 은 줄바꿈을 신경 쓰지 않으니 이렇게 써도 똑같이 동작합니다.
커서가 어디로 가는지 보세요.
정리하면 이렇습니다.
| 순서 | 무엇 | 몇 번 |
|---|---|---|
| 1 | 시작 (int i = 0) |
딱 한 번 |
| 2 | 조건 (i < 3) |
매 회차 시작 전 |
| 3 | 본문 | 조건이 참일 때만 |
| 4 | 변화 (i++) |
본문이 끝난 뒤 |
그리고 2번으로 돌아갑니다. 1번으로는 다시 가지 않습니다.
여기서 초보자가 가장 많이 헷갈리는 것이 4번입니다.
i++ 가 괄호 안에서 조건 바로 다음에 적혀 있으니 조건 다음에 실행될 것 같지만,
본문 다음입니다.
그래서 본문 안에서 보는 i 는 언제나 증가하기 전 값입니다.
i < 3 인 반복문의 본문에서 i 는 0, 1, 2 이고 3은 절대 나오지 않습니다.
회차별로 값이 어떻게 도는가
for (int i = 0; i < 5; i++) 를 표로 펼치면 이렇습니다.
| 회차 | 조건 검사 | 본문의 i | 증가 후 |
|---|---|---|---|
| 1 | 0 < 5 참 |
0 | 1 |
| 2 | 1 < 5 참 |
1 | 2 |
| 3 | 2 < 5 참 |
2 | 3 |
| 4 | 3 < 5 참 |
3 | 4 |
| 5 | 4 < 5 참 |
4 | 5 |
| - | 5 < 5 거짓 |
- | 종료 |
본문은 다섯 번 돌고, i 는 0부터 4까지 나옵니다.
0 부터 5 미만이라고 쓰면 정확히 5번입니다.
앞에서 인덱스가 0부터라고 했습니다.
for (int i = 0; i < 길이; i++) 형태가 그렇게 굳어진 이유입니다.
첫 칸이 0이고 마지막 칸이 길이 - 1 이니 딱 맞아떨어집니다.
언제 for 를 쓰고 언제 while 을 쓰나
반복 횟수를 미리 알면 for, 모르면 while 입니다.
for (int i = 0; i < 10; i++) // 열 번 돈다는 것이 코드에 적혀 있다
while (!isGameOver) // 몇 번 돌지는 실행해 봐야 안다
글자 수만큼, 배열 칸 수만큼처럼 세어서 도는 일은 for 입니다.
입력이 들어올 때까지, 적이 다 죽을 때까지처럼 세지 못하는 일은 while 입니다.
정리
for는 시작, 계속 조건, 변화를 괄호 하나에 모은 문법입니다. 세미콜론 두 개로 나눕니다.while과 하는 일이 같습니다. 세 가지를 어디에 적느냐만 다릅니다.- 실행 순서는 시작 → 조건 → 본문 → 변화 → 조건 → 본문 … 입니다.
- 변화는 괄호에서 두 번째 칸 다음에 적히지만 본문이 끝난 뒤에 실행됩니다.
- 그래서 본문 안의
i는 항상 증가하기 전 값입니다. 0부터n 미만까지 돌면 정확히 n번입니다.- 횟수를 미리 알면
for, 모르면while.