[C++] 루프와 관계 표현식
for 루프의 각 부분
for 루프를 구성하는 각 부분들은 각자의 역할이 무엇인지 알기 쉬운 위치에 자리잡고 있다. 초기화(initialization), 조건 검사(test), 갱신(update)을 처리하는 for 루프의 세 제어 부분은 괄호로 묶여 있다.
for (initialization; test-expression; update-expression)
body
for 루프는 진입 조건(entry-condition) 루프이다. 따라서 각 루프 주기에 진입할 때 조건 검사 표현식이 평가된다.
표현식이 아닌 것과 구문
어떠한 표현시에도 세미콜론만 붙이면 구문이 된다. 그러나 그 역은 성립하지 않는다. 즉, 어떤 구문에서 세미콜론을 뺀다고 해서 모두 표현식이 되는 것은 아니다. 우리가 지금까지 배운 구문 가운데 리턴 구문이나 선언 구문, for 구문은 statement = expression + semicolon이라는 일반 형식을 따르고 있지 않다.
융통성 있는 규칙
for 구문을 작성할 때 약간의 기교를 요구하는 C의 루프 규칙에 C++는 한 가지 융통성을 부여하였다. 원래 C의 for 루프 구문은 다음과 같았다.
for (expression; expression; expression)
statement
즉, for루프의 초기화 부분에 변수를 선언할 수 있다. 이것은 매우 편리하다. 그러나 선언은 표현식이 아니기 때문에 C의 루프 규칙에 맞지 않다. 한때 무법적이었던 이 행동은 선언에서 세미콜론을 없앤 declaration-statement expression이라는, for 구문에서만 사용할 수 있는 새로운 종류의 표현식으로 간주하도록 타협이 이루어졌다. 그러나 지금은 이 타협안이 폐기되고, for 구문의 구문 자체가 다음과 같이 수정되었다.
for (for-init-statement condition; expression)
statement
언뜻 보면 세미콜론이 하나뿐이어서 이상하다. 그러나 for-init-statement가 구문이고 자체에 세미콜론이 있기 때문에 문제가 없다. for-init-statement는 표현식-구문 또는 선언으로 간주된다.
증가 연산자(++)와 감소 연산자(--)
접두어(prefix) 방식은 ++x와 같이 피연산자 앞에 연산자를 사용하는 것이다. 접미어(postfix) 방식은 x++와 같이 피연산자 뒤에 연산자를 사용하는 것이다.
부수 효과와 시퀀스 포인트
부수 효과(side effect)는, 수식을 평가할 때 변수에 저장되어 있는 값과 같은 것이 변경될 때 일어나는 효과를 말한다. 시퀀스 포이트는, 프로그램의 실행이 다음 단계로 넘어가기 전에 모든 부수 효과들이 확실하게 평가되는 포인트이다.
y = (4 + x++) + (6 + x++);
수식 4 + x++는 완전 수식이 아니다. 그러므로 C++는 부분 수식 4 + x++가 평가된 직후에 x가 증가한다고 보장하지 않는다. 여기서 전체 식은 전체 대입문이고, 세미콜론이 시퀀스 포인트를 표시한다. 그래서 C++프로그램이 다음 명령문으로 이동할 때 x가 두 번 증가되었으리라는 것만 보장한다. C++는 부분 수식이 각각평가된 후에 x가 증가되었는지 또는 모든 수식의 평가를 끝낸 후에 x가 증가되었는지 구체적으로 규정하지 않는다. 이것은 이와 같은 종류의 구문들을 피해야하는 이유다.
접두어 방식과 접미어 방식
내장 데이터형에 대해서는 어느 방식을 사용해도 거의 차이가 없다. 사용자 정의 증가 연산자와 감소 연산자를 사용하는, 사용자 정의 데이터형에 대해서는 접두어 방식이 좀 더 효율적이다.
콤마 연산자
예를 들어, 매 루프 주가가 하나의 변수는 1씩 증가하고, 다른 하나의 변수는 1씩 감소해야 하는 루프가 필요하다고 가정하자. for 루프의 갱신 부분에서 이 두가지 일을 함께 처리할 수 있으면 무척 편리 할 것이다. 그러나 for 루프의 구문 규칙은 그 자리에 하나의 표현식만을 허용한다. 이 문제를 해결하는 방법은 콤마 연산자를 사용하여 두 개의 표현식을 하나로 결합하는 것이다.
int i, j;
for (j = 0; i = word.size()-1; j < i; --i, ++j)
body
while 루프
while 루프는 for 루프에서 초기화 부분과 갱신 부분을 없애고, 루프 몸체와 조건 검사 부분만 남겨 놓은 것이다.
while(test-expression)
body
프로그램은 먼저 괄호 안의 조건 검사 표현식 test-expression을 평가한다.
do while 루프
do while 루프는 for 루프나 while 루프와 달리, 탈출 조건(exit-condition) 루프이다.
do
body
while (test-expression);
Range 기반의 for 루프문(C++11)
C++11은 Range 기반의 for 루프라고 불리우는 새로운 형태가 추가되었다.
for (double &x: prices)
x *= 0.08;
Range 기반 for 루프는 초기화 리스트에도 사용 될 수 있다.