본문으로 바로가기

증감연산자의 원리

category ETC/knowledge 2018. 4. 1. 21:38

증감연산자.


++와 --의 형태를 띄며 전위/후위로 종류가 나뉜다



그러나 대부분 증감연산자를 공부할 때

전위는 먼저 계산하고, 후위는 해당 연산 종료 후 계산이라고만 알고 넘어간다.

나 역시 그랬었고 아래와 같은 문제에서 멘붕이 왔었다.



1
2
int a=10;
printf("%d %d %d %d %d\n", a++, a, ++a, a, ++a);
cs


위의 결과를 한번 생각해보자











[흔히 범하는 오류 1]


인자2. a++은 후위 연산자이므로 10이 출력된다

인자3. a는 10이 된다

인자4. ++a는 전위이므로 11이 된다

인자5. a는 4번과 마찬가지로 11이 된다

인자6. ++a는 전위이므로 12가 된다.


이 과정이 끝난 후에 후위연산이 진행되어 변수 a의 값은 13이 된다.


예상 출력 : 10 10 11 11 12









[흔히 범하는 오류 2]


인자2. a++은 후위 연산자이므로 10이 출력된다

인자3. a는 1번 과정에서 연산이 되었으므로 11이 된다

인자4. ++a는 전위이므로 12가 된다

인자5. a는 4번과 마찬가지로 12가 된다

인자6. ++a는 전위이므로 13이 된다.


예상 출력 : 10 11 12 12 13










실제로 해당 문제의 출력 결과는 아래와 같다


1
12 13 13 13 13
cs




왜 우리는 이 문제의 결과를 예측하지 못했을까?


나는 아래와 같은 개념이 부족하기 때문이라고 생각한다




첫째, 함수가 인자를 전달하는 매커니즘을 모른다


32bit 기준으로 생각하면 함수가 인자를 전달할 때 스택을 사용한다. 그러므로 위와같은 현상을 이해하기 위해선 스택이 무엇인지부터 알아보아야 하고, 스택이 LIFO구조이기 때문에 뒤의 인자를 먼저 스택에 넣어야 한다는 것을 깨달아야 한다. 쉽게말해 뒤에서부터 계산해야한다는 말이다.




둘째, 증감연산자의 전위, 후위에 따라 전달 방식이 다른것을 알지 못한다


단순히 전위의 경우 계산 후 연산, 후위의 경우 연산 후 계산이라는 말로만 이해하다보니 tmp = a++의 결과는 예측할 수 있지만 위의 문제처럼 조금만 복잡해져도 결과를 예측하기가 힘들어진다. 이를 알기 위해서는 실제로 전위, 후위가 어떻게 처리가 되는지 알아야 한다.


전위.

전위연산의 경우 해당 변수의 데이터를 증가시킨 후에 해당 변수의 주소값이 들어간다.

쉽게 설명하기 위해 아래와 같이 그 과정을 생각해볼 수 있다.


1
2
a+=1;
process(&a);
cs


즉, 데이터가 전달되는 것이 아니라 주소가 전달되기 때문에 해당 데이터를 사용하기 전에 변수의 값이 변경되면 데이터를 사용하려 할 때 주소를 참조하므로 변경된 값이 나오게 된다.


후위.

후위연산의 경우 해당 변수의 값이 임시로 저장된 후에 변수의 데이터가 증가하고, 임시 데이터를 넘겨준다.

이 역시 아래와 같이 그 과정을 쉽게 생각해볼 수 있다.


1
2
3
tmp = a;
a = tmp+1;
process(tmp);
cs


즉, 데이터가 먼저 보존되고, a의 데이터를 증가시킨다.






위의 코드가 정확한 코드가 아닐지라도 어느정도의 원리를 이해할 수 있고, 위를 인지하고 다시 문제를 풀어보면 복잡한 문제도 풀어낼 수 있다.