13.4 증감 연산자의 위치에 따른 차이점 알아보기

증감 연산자는 변수 앞에 사용할 수도 있고 뒤에 사용할 수도 있습니다. 여기서 증감 연산자만 단독으로 사용했을 때는 큰 차이가 없지만, 연산자를 사용한 뒤 다른 변수에 할당할 때는 위치에 따라 큰 차이가 있습니다.

먼저 증감 연산자를 변수 뒤에 사용했을 때입니다.

increment_decrement_postfix.c

#include <stdio.h>

int main()
{
    int num1 = 2;
    int num2 = 2;
    int num3;
    int num4;

    num3 = num1++;    // num1의 값을 num3에 할당한 뒤 num1의 값을 1 증가시킴
    num4 = num2--;    // num2의 값을 num4에 할당한 뒤 num2의 값을 1 감소시킴

    printf("%d %d\n", num3, num4);    // 2 2

    return 0;
}

실행 결과

2 2

2가 들어있는 num1, num2 뒤에 ++, -- 연산자를 사용한 다음 다른 변수에 할당하였습니다. 그런데 printf로 값을 출력해보면 값이 바뀌지 않고 2가 출력됩니다. 이는 증감 연산자의 가장 큰 특징입니다.

num3 = num1++;num4 = num2--;를 풀어서 쓰면 다음과 같습니다.

num3 = num1;
num1 = num1 + 1;

num4 = num2;
num2 = num2 - 1;

증감 연산자를 변수 뒤에 사용한 것을 후위(postfix) 연산자라고 하며 다른 변수에 할당했을 때의 동작 순서는 다음과 같습니다.

  1. 현재 변수의 값이 다른 변수에 할당됩니다(값의 변동이 없음).
  2. 증감 연산자가 수행되어 변수의 값이 1 증가(감소)됩니다.
그림 13‑1 후위 증가 연산자와 할당

후위 연산자는 할당 이후에 연산을 하게 되므로 바뀌기 전의 값이 다른 변수에 할당됩니다. 즉, 증감 연산자가 변수 뒤에 쓰이면 연산을 나중에 처리한다는 뜻이 됩니다.

이번에는 증감 연산자를 변수 앞에 사용해보겠습니다.

increment_decrement_prefix.c

#include <stdio.h>

int main()
{
    int num1 = 2;
    int num2 = 2;
    int num3;
    int num4;

    num3 = ++num1;    // num1의 값을 1 증가시킨 뒤 num3에 할당
    num4 = --num2;    // num2의 값을 1 감소시킨 뒤 num4에 할당

    printf("%d %d\n", num3, num4);    // 3 1

    return 0;
}

실행 결과

3 1

2가 들어있는 num1, num2 앞에 ++, -- 연산자를 사용한 다음 다른 변수에 할당하였습니다. 그리고 printf로 값을 출력해보면 증감 연산자가 동작하여 3, 1이 출력됩니다.

num3 = ++num1;num4 = --num2;를 풀어서 쓰면 다음과 같습니다.

num1 = num1 + 1;
num3 = num1;

num2 = num2 - 1;
num4 = num2;

증감 연산자를 변수 앞에 사용한 것을 전위(prefix) 연산자라고 하며 다른 변수에 할당했을 때의 동작 순서는 다음과 같습니다.

  1. 증감 연산자가 수행되어 변수의 값이 1 증가(감소)됩니다.
  2. 변수의 바뀐 값이 다른 변수에 할당됩니다.
그림 13‑2 전위 증가 연산자와 할당

전위 연산자는 할당 전에 연산을 하게 되므로 바뀐 값이 다른 변수에 할당됩니다. 즉, 증감 연산자가 변수 앞에 쓰이면 연산을 먼저 처리한다는 뜻이 됩니다.

참고

실제로는 num3 = num1++;이나 num3 = ++num1;과 같은 코드는 잘 안 씁니다. 요즘 추세는 다른 사람들도 쉽게 읽을 수 있는 코드 작성을 중요시합니다.

만약 C 언어 시험을 본다면 다음과 같은 코드의 결과를 묻기도 합니다.

int num1 = 2;
num1 = num1++ + ++num1;

답은 얼마일까요? 한 번 생각해보세요. 하지만 실무에서는 이런 코드를 아무도 작성하지 않습니다. 시험을 위한 시험 문제이지요(학점을 받기 위해 이런 시험 문제를 보는 분들은 힘내시길…).

실무에서는 num1++ + ++num1과 같은 복잡하고 애매한 코드 대신 조금 길더라도 의도가 명확하게 드러나도록 작성합니다. 세상 어디에서는 이런 코드를 작성하는 사람도 있겠죠. 하지만 협업이 이루어지는 실무에서 이런 코드를 작성했다가는 여러 사람이 피곤해질 수 있습니다.

변수에 할당하지 않고 함수의 인수로 사용했을 때도 동작 방식은 같습니다. 먼저 변수 뒤에 연산자를 사용해보겠습니다.

increment_decrement_postfix_argument.c

#include <stdio.h>

int main()
{
    int num1 = 2;
    int num2 = 2;

    printf("%d %d\n", num1++, num2--);    // 2 2: num1, num2의 값을 먼저 출력한 뒤 증감 연산자 동작
    printf("%d %d\n", num1, num2);        // 3 1: 증감 연산자가 동작한 결과

    return 0;
}

실행 결과

2 2
3 1

printf 함수 안에서 변수 뒤에 증감 연산자를 사용하면 바뀌기 전의 값이 먼저 출력된 다음에 연산자가 동작하여 값이 바뀝니다. 그러므로 printf 함수로 다시 변수의 값을 출력해보면 바뀐 값이 표시됩니다.

이번에는 변수 앞에 연산자를 사용해보겠습니다.

increment_decrement_prefix_argument.c

#include <stdio.h>

int main()
{
    int num1 = 2;
    int num2 = 2;

    printf("%d %d\n", ++num1, --num2);    // 3 1: 증감 연산자가 먼저 동작한 뒤 num1, num2의 값을 출력
    printf("%d %d\n", num1, num2);        // 3 1: 앞과 같은 값이 출력됨

    return 0;
}

실행 결과

3 1
3 1

printf 함수 안에서 변수 앞에 증감 연산자를 사용하면 연산자가 먼저 동작하여 바뀐 값이 출력됩니다. 그러므로 printf 함수로 다시 변수의 값을 출력해보면 같은 값이 표시됩니다.

이처럼 증감 연산자는 변수 앞에 오느냐 뒤에 오느냐에 따라 결과가 달라지므로 사용할 때 주의해야 합니다. 특히 이 부분은 눈에 잘 띄지 않는 부분이라 버그가 생기기 쉽습니다.