Notice
Recent Posts
Recent Comments
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- vector
- map
- 아두이노
- priority_queue
- C언어
- 라인트레이서
- arduino compiler
- Arduino
- list
- Array
- 시스템프로그래밍
- 통계학
- html
- 자료구조
- c++
- Algorithm
- queue
- 수광 소자
- 아두이노 컴파일러
- Stack
- directx
- 컴퓨터 그래픽스
- Visual Micro
- 운영체제
- LineTracer
- WinAPI
- Deque
- 아두이노 소스
- set
- stl
Archives
- Today
- Total
Kim's Programming
C언어 - 함수(function)(4/4) 본문
매크로 함수
매크로함수란 #define 전처리기를 이용하여 함수 흉내는 내는 것 입니다. 인수를 받아들일 수 있고 매크로로 실행 후 결과를 리턴한다는 것을 보면 함수와 비슷하다는 것을 볼 수 있습니다. 매크로 함수가 매크로 상수와 다른점은 함수처럼 인수를 받아 들인다는 것이고 인수 전달을 의미 하기 위해 매크로 이름 다음에 괄호를 이용하여 표기하게 됩니다. 간단한 매크로 함수는 다음과 같습니다.
1 |
#define twice(u) u+u; |
cs |
인수로 전달된 i를 두번 더함으로 이 값의 2배를 계산하게 됩니다. 예를 들어 twice(4)는 4+4=8로 치환이 되기 떄문에 결과적으로는 8로써 인식을 하게됩니다. #define문이 매크로 상수를 치환하는 방식과 같은 방식으로 매크로 함수도 치환을 하게되는데 인수자리에 매크로 함수의 실인수를 대체하게 된다는 점만 다릅니다. 하지만 매크로 함수의 정의는 위험이 따릅니다. #deinfe이 단순한 기계적인 치환에 불과하기 떄문에 다음과 같은 주의 사항이 필요합니다.
- 매크로 함수의 전체식을 괄호로 싸야합니다. twice 매크로 함수를 이용하여 나온 값의 음수값을 구하고 싶어서 -twice(4)라고 입력하게 되면 값은 -8이 나오지 않고 0이 나오게 됩니다. 왜 그렇게 되냐고요? 중간 값은 -4+4가 되어 0이 나오고 이유는 - 연산자와 +연산자의 계산 순서 때문에 그렇게 됩니다. 연산 우선순위의 영향을 피하기 위해서는 괄호를 이용하여 싸주어야 합니다. -(twice(4))라고 입력을 하게 되면 -(4+4)이기 떄문에 -8이라는 값이 나오게 됩니다. 괄호 연산자는 계산 우선순위가 가장 높기 때문에 치환식 전체를 감싸게 되면 치환된 식 우선으로 계산하게 되어 원하는 값이 나올 수 있게 됩니다.
- 매크로 인수들도 개별적으로 괄호로 싸줘야합니다. 왜냐하면 인수가 상수 또는 변수일 수도 있지만, 수식인 경우도 있는데 이경우는 인수 수식 자체가 먼저 평가가 되어야 되는 상황입니다. 예를 들어서 제곱값을 구하는 함수를 만드려고 다음과 값을 만들어 보았습니다. #define square(o) (o*o)라고 작성을 하게됩니다. 하지만! 여기서는 일반 변수를 대입했을 때는 아무런 문제가 없습니다. square(3) = 3*3 = 9라고 값을 출력할 것입니다. 하지만 인수에 수식이 들어간다면? square(1+2)=1+2*1+2 = 5? 다음과 같이 연산 순위에 따라서 다른 값이 나와 버렸습니다. 이를 방지 하기 위해서는 #define square(o) ((o)*(o))와 같이 작성을 해주어야합니다. 물론 잘못 계산이 되었어도 정상적인 값이 나오는 경우도 가끔은 있을 것입니다. 하지만 모든 경우에도 올바른 값을 출력하게 만드려면 괄호를 사용하여 예외 사항들은 보안해주어야합니다.
- 매크로 함수에서는 인수의 타입을 정하거나 점검할 필요는 없습니다. 매크로 함수가 아닌 함수는 전달 받을 인수의 타입이 원형에 이미 정해져있기 떄문에 정수형 인수에 실수를 넘기거나 부호가 틀려서 제대로 동작 하지 않는 경우가 많습니다. 하지만 매크로 함수는 인수를 치환만 하기 때문에 타입을 가리지 않습니다. 더해서 전처리 과정이기 때문에 점검 능력같은 경우 더욱 더 없습니다.
- 매크로 함수에 여러개의 명령을 동시에 포함시킬 수 있습니다. 자주사용하는 명령의 집합들을 매크로 함수로 합쳐 놓으면 편리합니다. 예를 들어 화면 특정 위치에서 메세지 출력하는 함수를 만들고 싶다면 다음과 같이 정의할 수 있습니다.
1#define printMessage(x,y,str) { gotoxy(x,y);puts(str);}cs
123#define printMessage(x,y,str)\{ gotoxy(x,y);\puts(str);}cs
다음과 같이 표기하면 더 알아보기가 좋아집니다. - 매크로 함수에서는 증감 연산자 (++, -- )와 복합연산자 ( +=, *=)등을 쓰지 않는 것이 좋습니다. 코드 자체에는 이상은 생기지 않지만 사용자가 결과를 예측하기가 너무 힘들기 때문입니다. 또한 예측이 힘들기 때문에 부작용이 발생할 여지도 있습니다. 웬만하면 '절대'라는 말을 붙여가면서 까지 절대 쓰지 않는 것이 좋습니다.
'Programming > C' 카테고리의 다른 글
기억 부류(Storage Class) (2/2) (0) | 2015.08.10 |
---|---|
기억 부류(Storage Class) (1/2) (0) | 2015.08.09 |
C언어 - 함수(function)(3/4) (0) | 2015.08.05 |
C언어 - 함수(function)(2/4) (0) | 2015.07.31 |
C언어 - 함수(function)(1/4) (0) | 2015.07.30 |