c언어 define문 : 상수를 정의할 때 쓴다.

코딩/C 2020. 7. 18. 16:08

 사실, 저는 백준을 풀 때 define 문을 상수 정의할 때 빼고는 써 본 적이 없었습니다. 실무에서는 어떻게 쓸 지는 잘 모르겠지만요. 상수 정의할 때도 가끔씩 써서, 그리 많이 쓴 적은 없습니다. 물론, C언어 시험 볼 때에는 많이 썼겠지만요. 보통 넓이를 구하는 것은 define이 아니라, 함수로 쓰는 편입니다.

 

 이것은, 배보다 배꼽이 더 커지기 때문에 그렇기도 합니다. 백준을 한참 할 때, 많이 본 질문 글 중 하나는 이것을 잘못 써서 맞았는데 왜 틀려요? 하는 경우였습니다. 전처리기에 대한 이야기는 나중에 정리할 때 한꺼번에 언급하기로 하고요. 오늘은 그냥 간단하게 개론만 보도록 하겠습니다.

 


 먼저 상수 정의할 때에는 요긴하게 쓰입니다. 이것은 제가 세그 트리를 구축할 때, (1<<20)-1을 쓰기 귀찮아서 SZ를 (1<<20)으로 재정의 한 다음에 SZ-1이나 SZ를 많이 써먹기도 합니다. 고수 분들의 코드를 보면 이런 용도로 쓰는 경우도 보실 수 있을 겁니다.

 

 

 이것은 간단합니다. 단지 PI라는 것을 3.14로 대치하겠다는 의미입니다. area 함수에서 r*r*PI를 리턴하는데요. 일단 결과부터 보고 이야기 해 보겠습니다. 반지름이 3인 원의 넓이를 구하는 코드입니다.

 

 

 대략 28.26이 나옵니다.

 

 

 이는 r*r*PI가 r*r*3.14로 대치되었기 때문입니다.

 

 

 /usr/include 안에 있는 math.h 정의를 보겠습니다. 몇 가지 유용한 상수들을 따로 재정의 했음을 알 수 있는데요. M_PI나 M_PI_2와 같은 (pi/2를 의미합니다) 것도 재정의 했음을 알 수 있습니다. pi/2나 pi/4 같은 경우에는, sin이나 cos 함수를 쓸 때 꽤 많이 넣는 것들 중 하나이니, 따로 재정의를 했으리라 생각합니다.

 

 

 stdio.h에 정의되어 있는 몇 가지 상수들입니다. EOF는 (-1)로, BUFSIZ는 8192 등으로 정의되어 있음을 알 수 있어요. 여기서 EOF는 (-1)로 정의했음을 알 수 있어요. -1이 아니라. 이 부분은 보고 가실 필요가 있습니다.

 


 그러면, 이런 경우에는 어떻게 될까요?

 

 일단 이 부분은 그리 어렵지 않게 이해할 수 있습니다. r이 3.0이고, 우리는 area(x)가 x*x*PI로 재정의 되었고 PI가 3.14니까, 어렵지 않게 28.2600000이 나올 거라는 것을 알 수 있습니다.

 

 그런데 이 경우에는 어떨까요?

 

 

 우리가 기대했던 값이 아니라 9.14라는 다소 엉뚱한  값이 나와버립니다.

 

 

 이는 area(r+1.0)이 위와 같이 대치되었기 때문입니다. x 부분을 단순히 r+1.0으로 치환했으니 r+1.0*r+1.0*3.14로 확장이 되었고, r의 값이 3.0이였으니, 9.14가 되는 것은 당연한 이치입니다.

 

 

 그러면 이 경우는 어떨까요?

 

 

 area(x)가 (x)*(x)*(PI)로 재졍의 되었습니다. 이 경우에는 area(r+1.0)이, (r+1.0)*(r+1.0)*PI로 확장이 됩니다. 따라서 예상하는 결과가 나옵니다. 그런데 이 경우에는 어떨까요?

 

 

 100.0에 area(r+1.0)을 나눈다. 결과가 1.9x가 나올 거 같습니다.

 

 

 그런데 뜬금없이 314.0이 출력되는데요. 이것은 100.0/area(r+1.0)이 아래와 같이 확장되기 때문입니다.

 

 

 당연하게도, /과 *은 우선순위가 같고, 좌에서 우로 결합하니까, 100.0/(r+1.0)이 먼저 계산이 될 겁니다. 그 다음에 (r+1.0)과 PI를 차례대로 곱합니다. 100.0/4.0이면 25고, 25에 4를 곱하고 3.14를 곱하면 314.00이 나오니까, 이상한 결과는 아닙니다.

 

 

 그렇기 때문에, 저는 이런 기능을 구현할 때에는 함수를 작성하는 편입니다. 왠만하면요.