C# while 반복문: 조건이 참인 동안 반복하다
C#에서 while 반복문은 특정 조건이 참인 동안 코드 블록을 반복적으로 실행하는 강력한 제어 흐름 문입니다. 이는 루프의 실행 횟수가 미리 정해지지 않고, 특정 조건이 충족될 때까지 작업을 계속해야 하는 시나리오에 특히 유용합니다. 게임 개발에서 while 루프는 애니메이션, 물리 시뮬레이션, 사용자 입력 처리 등 다양한 동적 프로세스를 관리하는 데 필수적인 도구로 활용됩니다.
while 반복문의 기본 구조
while 반복문의 기본적인 문법은 매우 간단합니다:
C#
while (조건)
{
// 조건이 참일 때 실행될 코드
}
여기서 조건은 불리언(Boolean) 값(참 또는 거짓)으로 평가되는 표현식입니다. 루프가 시작될 때 조건이 평가됩니다. 만약 조건이 true이면 중괄호 {} 안에 있는 코드 블록이 실행됩니다. 코드 블록의 실행이 완료되면, 제어는 다시 while 문으로 돌아와 조건을 다시 평가합니다. 이 과정은 조건이 false가 될 때까지 반복됩니다. 조건이 false가 되는 순간, 루프는 종료되고 제어는 while 루프 다음에 오는 코드로 넘어갑니다.
while 반복문의 작동 방식 예시
간단한 예시를 통해 while 반복문이 어떻게 작동하는지 살펴보겠습니다. 1부터 5까지의 숫자를 출력하는 코드입니다.
C#
int count = 1; // 루프 변수 초기화
while (count <= 5) // 조건: count가 5보다 작거나 같을 때까지
{
Console.WriteLine($"현재 숫자: {count}"); // 코드 블록 실행
count++; // count 값을 1 증가 (조건 변경)
}
Console.WriteLine("루프 종료!");
이 코드에서 count 변수는 1로 초기화됩니다. while 루프는 count <= 5라는 조건이 참인 동안 계속 실행됩니다.
count가 1일 때, 1 <= 5는 참이므로 "현재 숫자: 1"을 출력하고 count는 2가 됩니다.
count가 2일 때, 2 <= 5는 참이므로 "현재 숫자: 2"를 출력하고 count는 3이 됩니다.
이 과정은 count가 5가 될 때까지 반복됩니다.
count가 5일 때, 5 <= 5는 참이므로 "현재 숫자: 5"를 출력하고 count는 6이 됩니다.
count가 6이 되면, 6 <= 5는 거짓이므로 루프는 종료되고 "루프 종료!"가 출력됩니다.
이 예시에서 볼 수 있듯이, 루프 내에서 count 변수의 값을 변경하는 것이 중요합니다. 만약 count++와 같이 조건을 변경하는 코드가 없다면, count는 항상 1로 유지되어 count <= 5 조건이 항상 참이 됩니다. 이는 **무한 루프(Infinite Loop)**로 이어지며, 프로그램이 응답하지 않게 될 수 있습니다.
무한 루프와 주의사항
무한 루프는 while 반복문 사용 시 가장 흔히 저지를 수 있는 실수 중 하나입니다. 조건이 항상 true로 평가되는 경우 무한 루프가 발생합니다.
C#
int value = 0;
while (value < 10)
{
// 이 안에 value를 증가시키는 코드가 없다면?
Console.WriteLine("이 메시지는 무한히 출력됩니다!");
}
위의 코드에서 value는 항상 0이므로 value < 10은 항상 참이 됩니다. 따라서 "이 메시지는 무한히 출력됩니다!" 메시지가 계속해서 화면에 나타나게 됩니다. 무한 루프는 프로그램의 CPU 자원을 소모하고, 다른 작업의 실행을 방해하며, 결국 프로그램 충돌로 이어질 수 있습니다. 무한 루프를 방지하려면 루프 내에서 조건을 false로 만들 수 있는 논리를 항상 포함해야 합니다.
때로는 의도적으로 무한 루프를 생성해야 할 때도 있습니다. 예를 들어, 게임의 메인 루프는 일반적으로 while (true)와 같이 무한 루프로 구현되어 게임이 실행되는 동안 지속적으로 업데이트, 렌더링, 입력 처리 등을 수행합니다. 이 경우, 루프 내부에서 break 문을 사용하여 특정 조건이 충족될 때 루프를 강제로 종료하거나, 외부에서 프로그램을 종료하는 메커니즘을 제공해야 합니다.
break 문과 continue 문
while 루프의 흐름을 제어하는 데 사용할 수 있는 두 가지 중요한 키워드가 있습니다: break와 continue.
break 문
break 문은 현재 루프를 즉시 종료하고 루프 다음의 문장으로 제어를 이동시킵니다. 이는 특정 조건이 충족될 때 더 이상 루프를 진행할 필요가 없을 때 유용합니다.
C#
int i = 0;
while (i < 10)
{
Console.WriteLine($"i의 값: {i}");
if (i == 5)
{
Console.WriteLine("i가 5가 되어 루프를 중단합니다.");
break; // 루프 즉시 종료
}
i++;
}
Console.WriteLine("break 이후 루프를 빠져나왔습니다.");
이 코드에서 i가 5가 되는 순간 break 문이 실행되어 while 루프는 즉시 종료됩니다. 따라서 "i의 값: 6", "i의 값: 7" 등의 메시지는 출력되지 않습니다.
continue 문
continue 문은 현재 루프 반복의 나머지 부분을 건너뛰고 다음 반복으로 즉시 넘어갑니다. 즉, continue 문 이후의 현재 루프 블록 내의 코드는 실행되지 않고, while 조건으로 돌아가 다음 반복을 시작합니다.
C#
int j = 0;
while (j < 10)
{
j++; // j를 먼저 증가시켜 무한 루프 방지
if (j % 2 != 0) // j가 홀수이면
{
Console.WriteLine($"홀수 발견! {j}는 건너뜁니다.");
continue; // 다음 반복으로 이동
}
Console.WriteLine($"짝수: {j}"); // j가 짝수일 때만 실행
}
Console.WriteLine("continue 예제 루프 종료.");
이 예제에서는 j가 홀수일 때 continue 문이 실행되어 Console.WriteLine($"짝수: {j}"); 코드가 실행되지 않고 바로 다음 반복으로 넘어갑니다. 결과적으로 짝수만 출력됩니다.
while 반복문의 활용 사례 (게임 개발 관련)
Unity와 같은 게임 개발 환경에서 while 반복문은 다양한 시나리오에서 활용될 수 있습니다.
애니메이션 제어: 특정 조건이 충족될 때까지 캐릭터의 특정 움직임을 반복하거나, 시간에 따라 오브젝트의 위치를 부드럽게 이동시키는 트윈(tween) 효과를 구현할 때 사용할 수 있습니다.
C#
// (의사 코드) 특정 오브젝트가 목표 위치에 도달할 때까지 이동
Vector3 targetPosition;
float moveSpeed;
while (Vector3.Distance(transform.position, targetPosition) > 0.1f)
{
transform.position = Vector3.MoveTowards(transform.position, targetPosition, moveSpeed * Time.deltaTime);
yield return null; // Unity 코루틴에서 다음 프레임까지 대기
}
이 예시는 코루틴 내에서 while 루프를 사용하여 오브젝트가 목표 위치에 거의 도달할 때까지 매 프레임 이동하는 것을 보여줍니다.
리소스 로딩: 큰 게임에서 자산을 비동기적으로 로딩할 때, 로딩이 완료될 때까지 대기하는 루프를 사용할 수 있습니다.
C#
// (의사 코드) 자원 로딩이 완료될 때까지 대기
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync("MyGameScene");
asyncLoad.allowSceneActivation = false; // 즉시 활성화 방지
while (!asyncLoad.isDone)
{
// 로딩 진행률 표시
float progress = Mathf.Clamp01(asyncLoad.progress / 0.9f);
Debug.Log($"로딩 진행률: {progress * 100}%");
if (asyncLoad.progress >= 0.9f) // 로딩이 거의 완료되면
{
Debug.Log("로딩 완료! 키를 누르면 다음 씬으로.");
// 사용자 입력 대기 또는 특정 조건 후 씬 활성화
if (Input.anyKeyDown)
{
asyncLoad.allowSceneActivation = true;
}
}
yield return null;
}
Debug.Log("씬 활성화 완료!");
사용자 입력 대기: 특정 키 입력이나 마우스 클릭과 같은 사용자 입력을 기다릴 때 while 루프를 사용하여 다른 작업을 블로킹하지 않고 대기할 수 있습니다.
C#
// (의사 코드) 스페이스바를 누를 때까지 대기
while (!Input.GetKeyDown(KeyCode.Space))
{
Debug.Log("스페이스바를 눌러주세요...");
yield return null;
}
Debug.Log("스페이스바가 눌렸습니다!");
네트워크 통신 대기: 온라인 게임에서 서버로부터 응답이 올 때까지 대기하는 동안 while 루프를 사용하여 네트워크 상태를 확인하고 필요한 처리를 수행할 수 있습니다.
게임 로직 반복: 특정 턴 기반 게임에서 플레이어의 턴이 끝날 때까지 대기하거나, 적 AI가 행동을 완료할 때까지 반복하는 등의 로직을 구현할 수 있습니다.
do-while 반복문과의 비교
C#에는 while 루프와 유사한 do-while 루프도 있습니다. 주요 차이점은 조건 검사 시점에 있습니다.
while 루프: 루프 시작 전에 조건을 검사합니다. 조건이 처음부터 거짓이면 루프 내의 코드는 한 번도 실행되지 않을 수 있습니다.
do-while 루프: 루프 본문을 먼저 한 번 실행한 후에 조건을 검사합니다. 따라서 조건이 처음부터 거짓이더라도 루프 내의 코드는 최소 한 번은 실행됩니다.
C#
// while 루프 예시 (조건이 처음부터 false)
int x = 10;
while (x < 5)
{
Console.WriteLine("이 메시지는 출력되지 않습니다. (while)");
}
// do-while 루프 예시 (조건이 처음부터 false여도 한 번 실행)
int y = 10;
do
{
Console.WriteLine("이 메시지는 한 번 출력됩니다. (do-while)");
} while (y < 5);
어떤 루프를 사용할지는 특정 시나리오에 따라 달라집니다. 최소 한 번은 실행되어야 하는 작업이라면 do-while이 적합하고, 조건이 충족될 때만 실행되어야 하는 작업이라면 while이 적합합니다.