증감식 자리에서는 다음 루프의 변수를 지정하여 대입하도록 하는 것이다.
지정해놓지 않으면 그저 표현식에 불과하게 되고,
영원히 초기식은 변함 없이 초기식인 상태로 머물며,
그러므로 무한루프에 빠지게 되는 것이다.

for
반복할 특정 작업의 횟수가 명확할 때 사용
for (초기화식, 조건식, 증감식) { … }
예제1.
void main() {
for (var i = 1; i < 5; i++) {
print('hello $i');
}
}
/*
hello 1
hello 2
hello 3
hello 4
*/일단 요까지는 알겠는데,
요건 좀 헷갈리는기라.
예제2.
void main() {
for (int i = 1; i < 5; i++) {
print("hello ${i + 1}");
}
}
/*
hello 2
hello 3
hello 4
hello 5
*/이게 왜 헷갈리냐면,
이미 나는 증감식에서 ++1이라고 식을 넣어놨다.
예제1번에서 증감식만 넣어놓고 print($i)를 했을 때 1씩 증가하는 것을 확인했다.
예제2번은 증감식이 있고 거기에 더해서 print 안에 ${i + 1} 이라는 수식이 한 번 더 들어갔다.
그러면 내 예상에는 증감식이 적용되어서 1씩 증가하는 것에 더해, + 1의 처리까지 진행해야 하니, 2씩 증가하는 것이 옳지 않나? 라는 생각인데. 실제로는 위와 마찬가지로 1씩만 증가한다.
print($i) 와 print(${i + 1}) 은 다른 식인데, 왜 똑같이 1씩만 증가하나?
물론 결과값이 다르긴 하다. 예제1에서는 첫 값이 1로 나왔지만, 예제2는 2이니.
그치만 나의 헷갈리는 포인트는: 왜 2씩 증가하지 않는가.
가설을 검증하기 위해 다음과 같은 예제를 돌려보았다.
예제3 (따라하지 마세요)
void main() {
for (int i = 1; i < 2; i * 2) {
print("hello ${i + 1}");
}
}
결과는?? 무한 루프의 덫에 걸림…
왜지?
i는 1이고
→ [조건식] 1은 5보다 작다
→ [증감식] 그렇다면 i의 5배를 해라. [조건식] 언제까지? i가 5보다 작을 때까지.[예상]
/*
5
10
15
20
*/[실제] :
hello 5를 산출해놓고, 무한히 돌아감.[이해 안되는 점]
i는 변수의 이름이고, 1회 print한 그 결과값을 다시 i에 넣는 게 아닌데. 왜 무한 돌아가는 거임?i 에 넣는 거라면 두 번째 턴에서
i = 2라는 말인데, 그건 아닐 거같고.
그랬으면 세 번째 턴에서 i = 4가 되고, 네 번째 턴에서는 6이 되니 멈췄어야 하지 않나?
[GPT의 답변}
여기서 네 코드는
초기식: int i = 1;
조건식: i < 5;
변화식: i * 5 ← 문제 지점
핵심 문제: i * 5는 그냥 계산만 하고 버리는 표현식이야
i * 5는 “i에 5를 곱한 값을 계산”만 할 뿐
그 값을 어디에도 대입하지 않아서 i는 여전히 1 그대로야
그러니까 매 반복마다 상황이 이렇게 됨:
i = 1으로 시작
조건 i < 5 → 1 < 5 → true → 블록 실행
print("hello ${i + 1}") → hello 2 출력
변화식 실행: i * 5 → 1 * 5 = 5 계산만 하고 버림
→ i는 여전히 1
다시 조건 검사: i < 5 → 또 true → 또 실행…
그래서 콘솔에 hello 2만 계속 찍히는 거.이라는데…
아니 그럼 이 말에 따르면,
예제2에서 i는 회차수가 아니라, 직전 회차수에 나온 결과값이라는 얘기야?
GPT의 답변을 들어본다.
관건은 딱 두 군데 오해야.
- for문에서 증감식은 본문보다 “나중에” 실행된다.
- i * 5는 그냥 “계산만 하고 버리는 값”이라서 i 값이 안 바뀐다.
이 두 개만 바로 잡으면 지금 헷갈린 거 싹 정리돼.
1. 첫 번째 코드부터 다시 뜯자
for (int i = 1; i < 5; i++) {
print("hello ${i + 1}");
}
for(초기식; 조건식; 증감식)의 실행 순서는 항상 이렇게야:
초기식 1번만 실행
조건식 검사
조건식이 true면 본문 실행
본문 끝난 뒤에 증감식 실행
다시 2로 돌아감
이걸 while로 바꾸면 이렇게 되는 거랑 같다:
int i = 1; // 초기식
while (i < 5) { // 조건식
print("hello ${i + 1}"); // 본문
i++; // 증감식
}
이제 회차별로 진짜 순서대로 보면:
1회차
시작: i = 1
조건 검사: i < 5 → 1 < 5 → true
본문 실행: print("hello ${i + 1}") → i는 아직 1 → 1 + 1 = 2 → hello 2
증감식 실행: i++ → i = 2
👉 그래서 1회차 출력은 2가 맞다.
네가 말한 “증감식에 의해 i값이 1 올려진 후에 print가 실행된다”가 아니라,
항상 “print → 그 다음에 i++” 이 순서야.
2회차
시작 시점의 i: 1회차 끝에서 2가 되어 있음
조건: 2 < 5 → true
본문: print("hello ${i + 1}") → 2 + 1 = 3 → hello 3
증감식: i++ → i = 3일단, 증감식이 맨 마지막에 작동한다는 것은 중요하게 이해했다.
그러니까 회차가 증가할 때마다 i가 1씩 증가하는 것은 i++이라는 증감식에 의거해 그랬던 것. print 문 내에 있는 i + 1이라는 것은 결과값일 뿐, 결과값이 그 다음 루프의 i에 대입되는 것은 아니다. 이건 아주 중요한 깨달음!
그러나, 그렇다 하더라도!
증감식이 마지막에 계산되는거라매. 내가 for문의 {} 이 안에다가 *5를 넣은게 아니고, 증감식에다가 넣었잖아.
네 말에 따르면 증감식은 마지막에 돌아가는 거니까, 1회차 루프에서 i = 1, 1 + 1 = 2, 결과값 hello 2 여기까진 이해했어. 그치만 마지막 단계인 증감식에 따라 i = 5로 바뀐다는 거지?
그러면 2회차에서 i = 5니까, 멈춰야되는 거 아니야?
그리고 GPT의 다음 답변에서 나는 제대로 배웠다.
핵심만 요약하자면.
i * 5; // 그냥 '계산만' 한다. i는 그대로.
i = i * 5; // 계산한 값을 i에 '다시 집어넣는다'. 그래서 i가 바뀐다.
i *= 5; // 위랑 완전히 같은 뜻. (축약형)
i++; // i = i + 1; 의 축약형. i를 실제로 1 증가시킴.그렇다. 나는 i에 5를 곱했을 뿐, 그것을 i 값으로 지정하지 않은 것이다!!!
💡
유레카….!!
미친듯이 깨달아버렸다.
예제1과 2에서 사용한 i++은 i = i + 1의 축약으로, 대입 연산자가 포함되어 있던 것이다!!!
서울대생이 종종 느낀다는 학문 오르가즘이란 이런 걸까.
도파민 터지는 기분…
void main() {
for (int i = 1; i < 5; i = i * 2) {
print("hello ${i + 1}");
}
}
/*
hello 2
hello 3
hello 5
*/증감식에 대입 연산자 =를 넣으니 내 의도대로 작동하였다.
for문은 정복한 기분이다.
만족스럽다..