4-5-나.break

break문은 이미 앞에서 여러 번 사용해 본 바 있다. 이 명령은 반복문이나 switch문 내에서 사용되며 루프를 강제로 벗어날 때 사용한다. for문이나 while문 내에서 break가 사용되면 조건식의 진위 여부에 상관없이 즉시 루프를 탈출하는데 우리말로 번역하자면 "당장 튀어 나와"라고 할 수 있다. 보통 if 조건문과 함께 사용되며 무한 루프에서 루프를 끝낼 조건이 되었을 때 break를 사용한다.

여러 개의 루프가 중첩되어 있는 다중 루프에서 break문이 사용되면 현재 루프 하나만 탈출한다. 다음은 이중 루프의 예이다.

 

for (i=...) {

     for (j=...) {

          break;

     }

}

 

이 경우 j루프의 명령 블록에 있는 break는 j루프만 탈출하도록 하며 i루프까지 한꺼번에 탈출하지는 못한다. 특정한 조건이 되었을 때 이중 루프를 탈출하도록 하고 싶다면 탈출 변수를 사용하거나 아니면 루프의 구조를 단순 루프로 바꾸어야 한다. 탈출 변수란 루프를 끝낼 것인가 아닌가를 기억하는 변수이며 루프의 계속 여부만을 통제하는 일종의 제어 변수라고 생각하면 된다.

 

flag=0;

for (i=...) {

     for (j=...) {

          flag=1;

          break;

     }

     if (flag == 1) break;

}

 

이중 루프에 들어가기 전에 탈출 변수에 0을 대입해 놓는다. 이 변수가 0인 동안은 (flag == 1)조건이 거짓이므로 루프가 정상적으로 반복될 것이다. 안쪽 루프에서 바깥쪽 루프까지 한꺼번에 탈출하려면 break를 하기 전에 flag에 1을 대입해 놓고 탈출한다. 바깥쪽 루프는 안쪽 루프가 끝나자 마자 flag값을 보고 이 값이 1이면 안쪽 루프에서 모든 루프의 종료를 원한다는 것으로 인식하고 자신도 반복을 종료하고 즉시 탈출한다.

만약 안쪽 루프에서 자기 자신만 종료하고 바깥쪽 루프는 그대로 실행되도록 하고 싶다면 탈출 변수값을 바꾸지 말고 break만 하면 된다. 이런 식으로 탈출 변수를 사용하면 이중, 삼중으로 루프가 중첩되어 있더라도 줄줄이 루프를 계속 벗어날 수 있다. 조금 구질 구질해 보이고 왠지 꽁수같아 보이지만 이중 루프 정도라면 이 방법도 그리 나쁘지 않다.

탈출 변수를 쓰는 방법외에 제어 변수를 직접 조작하는 방법도 있다. 안쪽 루프를 탈출할 때 바깥쪽 루프가 종료될 조건을 만들어 놓고 break하면 바깥쪽 루프의 조건식에 의해 자연히 바깥쪽 루프도 끝나게 된다.

 

for (i=1;i<10;i=i+1) {

     for (j=1;j<5;j=j+1) {

          i=10;

          break;

     }

     // 여기에 다른 명령이 없어야 한다.

}

 

바깥쪽 루프의 조건식이 "10보다 더 작다"이므로 안쪽 루프에서 i를 강제로 10으로 바꾼 후 break하면 바깥쪽 루프가 자연스럽게 종료된다. 그러나 이 방법은 안쪽 루프 다음에 다른 명령이 또 있을 경우에는 쓸 수 없으며 제어 변수를 강제로 조작한다는 면에서 별로 바람직하지는 않다. 다중 루프를 탈출하는 방법이 어렵다면 마지막으로 선택할 수 있는 가장 쉬운 방법이 있는데 바로 goto문이다.

 

for (i=1;i<10;i=i+1) {

     for (j=1;j<5;j=j+1) {

          goto outside;

     }

}

outside:

 

goto는 무조건 분기문이므로 루프가 몇겹으로 싸여 있더라도 지정한 레이블 위치로 즉시 점프한다. 4중, 5중 다중 루프를 탈출할 때는 사실 goto만큼 효율적인 명령이 없으며 goto문을 꼭 사용해야 할 특수한 경우가 바로 이런 경우이다. goto의 또 다른 활용예로 자원 해제 코드를 한 곳에 모아 두고자 할 때를 들 수 있는데 이런 예도 다음에 보게 될 것이다. 남발하지만 않는다면 이럴 때는 goto를 한 번쯤 써도 상관없다.