5-1-라.증감 연산자

증감 연산자는 피연산자를 1씩 증가시키거나 감소시킨다. 루프의 제어 변수처럼 순서대로 어떤 작업을 할 때는 변수값을 하나씩 증감시키는 경우가 많기 때문에 별도의 연산자가 마련되어 있다. 증가 연산자는 ++로 쓰며 감소 연산자는 --를 쓴다. 둘 다 사용 방법은 비슷하므로 ++연산자에 대해서만 집중적으로 연구해 보자. 다음 세 식은 모두 동일하며 a를 1 증가시킨다.

 

a=a+1    ② a+=1    ③ a++

 

a에 1을 더한 값을 다시 a에 대입함으로써 a를 1만큼 증가시키는데 이 대입문은 앞에서 배운 복합 대입문 a+=1로 바꿀 수 있다. 증가 연산자를 사용하면 더 짧고 간단해지는데 루프의 제어 변수를 증가시킬 때 ++ 연산자를 많이 사용한다.

 

for (i=1;i<=10;i++) 명령;

 

이렇게 루프를 구성하면 i가 1부터 시작해서 10까지 1씩 계속 증가하면서 명령을 반복한다. 이 간단한 연산자는 아주 직관적이고 편리해서 C언어를 대중화시키는데 결정적인 기여를 했으며 예로부터 C프로그래머들의 자랑거리중 하나였었다. 증감 연산자는 증감시킬 값이 1로 고정되어 있으며 증감시킬 대상이 되는 피연산자를 하나만 취하므로 단항 연산자이다. 증감 연산자는 피연산자의 앞에 쓰이는 경우와 뒤에 쓰이는 경우 두 가지 형식으로 사용된다.

 

전위형(Prefix) : 증감연산자가 피연산자 앞에 위치한다. ++a, --a

후위형(Postfix) : 증감연산자가 피연산자 뒤에 위치한다. a++, a--

 

두 방식은 단독으로 사용될 때는 차이가 없지만 수식내에서 사용될 때는 약간의 차이가 있다. 전위형은 일단 값을 먼저 증감시킨 후 그 결과를 리턴하지만 후위형은 값을 먼저 리턴하고 증감시킨다. 다음 예제를 보자.

 

: increase

#include <Turboc.h>

 

void main()

{

     int i;

 

     i=3;

     printf("전위형으로 썼을 때 : %d\n",++i);

 

     i=3;

     printf("후위형으로 썼을 때 : %d\n",i++);

}

 

i에 3을 대입하고 i를 ++연산자로 1증가시켜 그 값을 printf로 출력하되 한 번은 전위형으로, 한 번은 후위형으로 증가시켰다. 결과는 다음과 같다.

 

전위형으로 썼을 때 : 4

후위형으로 썼을 때 : 3

 

전위형 ++i 문은 i를 1먼저 증가시킨 후 그 결과인 4를 리턴하므로 printf는 4를 출력할 것이다. 이 문장을 둘로 나누면 다음과 같이 분리된다.

 

++i;

printf("전위형으로 썼을 때 : %d\n",i);

 

반면 후위형의 i++문은 i값을 먼저 리턴하고 i를 1증가시키므로 printf는 3을 출력할 것이다. 이 문장은 다음과 같이 분리된다.

 

printf("후위형으로 썼을 때 : %d\n",i);

i++;

 

두 경우 모두 출력이 끝난 후 i는 똑같이 4가 되지만 수식내에서 평가되는 증감식 자체의 값은 다르다. 값이 먼저 평가되고 증가되는가 증가된 후 평가되는가의 차이점으로 인해 출력되는 값이 달라지는 것이다. 다음 코드는 전위형과 후위형의 차이를 좀 더 분명히 보여준다.

 

int i=0;

while (++i < 5) {

     printf("%d\n",i);

}

 

i를 0으로 초기화하고 i가 5보다 작은동안에 i값을 출력하되 while 조건문에서 i값을 전위형으로 증가시키고 있다. 이 경우 i값이 먼저 증가되고 평가되므로 i가 5가 되는 시점은 while문의 조건이 거짓이 되어 5는 루프에서 제외된다. 그러나 while (i++ < 5)의 후위형으로 바꾸면 i값이 평가된 후 증가하기 때문에 i가 4일 때 일단 조건을 만족시킨 후 i가 증가하므로 5도 루프에 포함된다. 전위형, 후위형에 따라 루프의 반복 회수가 달라지는 것이다.

그러나 이런 차이는 어디까지나 수식내에서 사용될 때 뿐이며 증감식이 단독으로 사용될 때는 전위형이나 후위형이나 차이가 전혀 없다. 그래서 다음 두 루프는 완전히 동일하다.

 

for (i=1;i<=10;i++) 명령;

for (i=1;i<=10;++i) 명령;

 

증감식이 for문의 일부로 존재하고 있지만 이 식이 실행될 때는 단독으로 실행된다. 조건식과 증감식이 각각 따로 실행되는 것이지 동시에 실행되는 것이 아니다. 둘 중 어떤 형태를 쓰더라도 상관없지만 for문에서 제어 변수를 증감시킬 때는 보통 후위형을 많이 사용한다. 왜냐하면 사람은 보통 증가시키는 동작보다 대상을 먼저 선택하는 버릇이 있기 때문이다.

증감 연산자는 피연산자의 값을 변경한다는 점에서 대입 연산자와 비슷하다. a++이 a=a+1과 같으므로 증감 연산자도 대입 연산자와 마찬가지로 좌변값만 피연산자로 취할 수 있다. 즉 증가시킬 수 있는 대상에 대해서만 제대로 동작한다. 1++과 같이 상수를 1증가시키는 것은 당연히 안되며 (a+1)++ 이런 식도 사용할 수 없다. 1이나 (a+1)은 좌변값이 아님을 직관적으로 이해할 수 있을 것이다. ++ 연산자에 대한 가장 흔한 오해는 이 연산자를 두 번 쓰면 2 증가할 것이라고 상상하는 것이다.

 

a++++;

 

이렇게 쓰면 a가 2증가할 것 같지만 이 문장은 에러다. 혹시 괄호를 빼먹어서 컴파일러가 헷갈리는가 싶어서 (a++)++ 요렇게 해도 마찬가지고 +가 한꺼번에 너무 많이 와서 그런가 싶어 ++a++같이 해도 역시 에러다. 왜냐하면 a는 변수이고 좌변값이지만 a를 1증가시킨 결과는 정수 상수이지 더 이상 좌변값이 아니기 때문이다. ++ 연산자를 전위형으로 사용하여 ++++a; 라고 쓰는 것은 가능하지만 역시 일반적이지 않다. a를 2 증가시키고 싶으면 저런 이상한 코드를 생각하지 말고 a+=2; 를 쓰는 것이 가장 합리적이며 그것도 자신없으면 a=a+2; 라고 풀어 쓰는 편이 더 좋다.