F.R.I.D.A.Y.

함수 인자로 단항연산자 사용하기 본문

DEV/C C++

함수 인자로 단항연산자 사용하기

F.R.I.D.A.Y. 2019. 6. 25. 01:33
반응형

 연산자 중에 단항 연산자(++, -- 등)는 일반 사칙 연산자에 비해 속도가 빠른 편입니다. 물론 컴파일러에 따라 속도 문제가 해결이 되긴 하지만 기본은 단항 연산자가 더 빠릅니다. 편하기도 합니다. 그래서 자주 사용하지만, 조심해야 하는 위치가 있습니다. 오늘은 단항 연산자의 사용을 지양해야 하는 위치를 알아봅니다.

 

※ Visual Studio 2019 Community v16.1.3. 기준으로 작성되었습니다.


단항 연산자 특성

 일단 단항 연산자의 특성을 알아봅시다. 단항 연산자는 기본적으로 연산의 결과가 피연산자의 값에 영향을 주므로 실제 피연산자의 값이 변경되는 위치에 사용되어선 안됩니다. 대표적으로 문자열을 저장하는 포인터에 단항 연산자 사용은 위험한 행동입니다. 다음 코드를 보겠습니다.

#include <stdio.h>

int main(void) {

	char* pStr = "Hello World";


	for (int i = 0; i < 11; ++i) {
		printf("%s\n", pStr + i);
	}
	
	return 0;
}

 위 코드는 Hello World! 문자열을 출력하며, for문이 한 번 돌 때마다 앞의 한 글자씩을 제외하고 출력하는 예제입니다. 따라서 위 코드를 실행하면 아래와 같이 나오게 됩니다.

한 글자씩 밀려 출력됩니다.

 그런데 만일 Hello World라는 문자열을 다른 위치에서 사용하려고 한다면 어떨까요? 즉, 아래와 같은 예시일 경우엔 어떻게 출력이 이루어질까요?

#include <stdio.h>

int main(void) {

	char* pStr = "Hello World";


	for (int i = 0; i < 11; ++i) {
		printf("%s\n", pStr + i);
	}
	
	printf("%s\n", pStr); // 추가된 코드, Hello World를 추가로 한 줄 출력합니다.

	return 0;
}

 분명 정상적으로 출력됩니다. 아직 위 코드에서는 pStr의 값을 수정하지 않았으니까요.

마지막 한 줄에 정상적으로 출력된 Hello World 문자열

 그러나 for문의 printf에서 pStr + i를 pStr++로 수정해봅니다.

 정상적으로 출력이 이루어지지 않습니다. 원인은 단항 연산자(++)가 pStr의 값을 수정했기 때문입니다.

 따라서 문자열이나 할당받은 메모리 등을 이용할 때는 단항 연산자의 사용을 지양해야 합니다. 


함수 인자로 단항 연산자 사용하기

 위에서 예시로 들었던 것은 그 예측이 비교적 잘 됩니다. 그러나 이번에 작성할 것은 조금 다릅니다. 다음 코드의 결과를 예측해보세요. 결과는 코드 아래 몇 줄 뛰고 작성해놓겠습니다.

#include <stdio.h>

void test(int a, int b, int c, int d) {
	printf("%d %d %d %d\n", a, b, c, d);

}

int main(void) {

	int i = 1;

	test(i++, ++i, ++i, i++);
	
	return 0;
}

 

 

 

 

 

 결과는 < 4 5 5 1 > 이 나옵니다. 사실 이 결과가 나오지 않는 분도 있습니다. 이 단항 연산자의 연산 순서는 컴파일러의 해석 순서에서도 차이가 납니다. 옛날엔 시험에 이런 문제도 나왔다고 하네요. 일단 문제를 내긴 해야 하니 억지로 냈다고 합니다. 요즘 이런 문제를 학교에서 만난다? 심지어 컴파일러(제품, 버전)도 명시가 되어있지 않다? 가서 따지시면 됩니다.

 

 차근히 풀어봅니다. 연산 순서는 오른쪽에서 왼쪽으로 차례대로입니다.

처음 연산되는 오른쪽( i++); )과 마지막으로 연산되는 왼쪽( (i++, )

 사실, 저도 초반엔 이 것 때문에 문제를 많이 맞닥뜨렸습니다. 이것 외에도 함수에 단항 연산자를 사용하면 예상과 달리 작동하는 경우가 많기 때문에 단항 연산자는 함수의 인자로 사용할 때 특히나 주의해야 합니다.


함수 인자에서 단항 연산자 이해하기

#include <stdio.h>

void print(int val) {
	if (val < 0) return;
	printf("%d ", val);
	print(val--);
}

int main(void) {

	print(10);

	return 0;
}

 문제없이 컴파일이 진행됩니다. print() 함수에서 자신을 호출하니 재귀 함수로군요. 10부터 0까지 출력하는 코드네요. 그런데 문제가 있습니다. 이 문제가 무엇인지 찾아서 비밀댓글로 작성해보세요. 이 문제를 한 번에 알아챘다면 함수 인자에서 단항 연산자의 문제를 잘 인지하고 있다고 볼 수 있겠습니다.


참고사항

문자열의 관리 방식 (포스트)

728x90
반응형

'DEV > C C++' 카테고리의 다른 글

키워드와 예약어  (0) 2019.08.08
scanf()의 문제점  (0) 2019.06.25
C 스타일의 문자열 관리 방식  (0) 2019.06.25
sizeof 연산자의 오용  (0) 2019.06.17
sizeof 연산자  (0) 2019.06.17
Comments