본문 바로가기

무언가 만들기 위한 지식/C,C++,Embedded C

[ALL] Macro(매크로_전처리기 #define)

C언어에서 사용되는 기능중 Macro 기능을 알아보자.
일단 매크로의 정의는 네이버 백과사전에 다음과 같이 나와 있다.

자주 사용하는 여러 개의 명령어를 묶어서 하나의 키 입력 동작으로 만든 것을 매크로라고 한다. 여러번 해야 하는 일을 간단하게 수행하기 위하여 사용하기도 하지만, 문서 안의 같은 문자열을 한꺼번에 변경 할 때도 사용된다.

이 매크로 기능은 전처리기 #define에 의해서 이루어 진다.
(전처리기-Preprocessor는 compiler 실행 직전에 컴파일시 가장 먼저 수행되는 과정이다.)

정확한 기능은 전처리 과정에서,
해당 define된 변수를 Code상에서 치환시켜주는 역할을 한다.

function이나 subroutine과는 다르게 분기하여 실행되는 것이 아니라, define에 의해 정의된 코드가 해당 위치로 치환된다.
이는 함수 호출과 관련한 오버헤드를 줄일 수 있어, 어느정도 속도의 향상을 꾀할 수 있지만, 최종 실행파일의 크기는 커지게 된다. (임베디드 시스템에서 주로 비트연산등 어느정도 가벼운 연산에 활용된다.)

define을 이용하는 법은 두가지가 있다.
첫째는 단순히 매크로명을 대응 문자열 또는 상수로 치환하는 것이고,
둘째는 매크로 함수를 이용하여 만드는 것이다. (=모든 함수를 매크로화하면 프로그램전체 크기가 커지게 되고, 메모리 사용량을 늘리게 된다. 매번 계산되므로 인자의 수식이 복잡하다면 CPU시간을 증가시킨다.)

※ 컴파일러에 따라 문자수 제한이 있을 수 있으며, 디버깅이 힘들다.

define은 즉, 매크로명으로 된 부분이 처음 정의된 값으로 전처리기 수행때 치환된다고 보면된다.
(상수는 상수로, 스트링은 스트링으로)
define 사용시, 문자열이나 문자 정수 속에는 치환이 발생하지 않으며, 매크로 함수 사용시 인자를 정의하는 ()를 매크로함수명 다음에 공백을 두지 않고 바로 사용하여야 한다.

일반적으로 define의 사용은 프로그램의 명확성과 이식성을 증대시켜준다.
(define이 된 문서를 헤더파일로 작성하여 공용으로 사용한다. 자주 사용되는 상수등을 정의하여 사용하거나, 타입을 지정한다. 또는 간단한 매크로 함수를 비트연산등에 이용)

[작성환경 : Window XP   작성툴 : Visual Studio 6.0   컴파일러 : Visual Studio 6.0    사용언어 : C]


간단하게 MACRO를 적용해 보았다.
보시다시피 전처리기 define을 이용하였다.
2 Line의 경우는 정수를 3 Line의 경우에는 문자열을 각각 치환하도록 하였다.
4~7 Line은 매크로함수를 더하기와 곱하기로 정의해보았다.
여기서 주의해야할 점은 매크로함수내의 수행될 부분을 명확히 하기 위해여 "()" 잘 사용하여야 한다는 것이다.
13~14 Line을 확인해보면 같은 MUL1, MUL2 매크로함수에 "()"를 명확히 정의하지 않을 경우 어떤 문제가 생기는지를 보여준다. MACRO는 치환되는 것이기 때문에 가로를 명확히 적지 않으면 그대로 치환된다. 즉 연산자 우선순위가 나중에 고려된다.
그렇기 때문에 전혀 의도 하지 않은 답이 될 수 있다. 매크로함수는 디버깅하기도 까다롭기 때문에 명확히 이해하고 사용되어야 한다. 아래 결과값에서 MUL1MUL2가 전혀 다른값을 계산해 내고 있다.
또한 15~16 Line은 Macro를 중첩해서 사용해본 것이고,
17 Line은 조건 3항연산자를 적용해 본것이다.


<매크로 와 매크로 함수 Test한 결과 값>