[C] 전처리기
전처리
선행처리란, 행 파일을 생성하는 과정에서 소스 파일 내에 존재하는 전처리문을 모두 치환하는 작업이다. 이러한 전처리 작업은 컴파일하기 전 전처리기에 의해 먼저 처리된다.
전처리기는 코드를 생성하는 것이 아니라, 컴파일러가 컴파일하기 좋도록 소스를 재구성해주는 역할만을 한다.
전처리문
1)전처리 문자(#)로 시작한다.
2)코드 내에서 하나의 라인을 모두 차지하며, 전처리문 뒤에 C언어 코드를 추가하여 같이 사용할 수 없다. (주석 예외)
3)맨 뒤에 세미콜론을 붙이지 않는다.
4)전처리문은 어디서나 작성 가능하지만, 전처리문은 그 문장이 위치한 곳에서부터 파일 끝에까지만 기능한다.
전처리 지시자
1)#include
해당 전처리 지시자는 외부에 선언된 함수나 상수 등을 사용하기 위해서 헤더 파일을 현재 파일에 포함할 때 사용된다.
#include <stido.h>(표준 헤더파일 포함 시 주로 사용) 또는 #include "myStdio.h" (사용자 정의 헤더파일 포함 시 주로 사용) 과 같이 쓰일 수 있다.
2)#define
함수나 상수를 단순화해주는 매크로를 정의할 때 사용한다.
#define 식별자 대체리스트
매크로 함수
#define 선행처리 지시문에 인수로 함수의 정의를 전달함으로써, 함수처럼 동작하는 매크로를 만들 수 있다.
ex) #define product(x,y) x*y
*주의: 매크로 함수는 단순히 치환만 진행해주기 때문에 (x)*(y) 처럼 괄호를 쳐주어야 한다. 그렇지 않으면
x에 x+7과 같이 넣어주는 경우 x+7*x+7으로 진행된다.
장점
1)단순 치환만을 해주므로, 매개변수의 타입을 신경쓰지 않는다.
2)여러 개의 명령문을 동시에 포함할 수 있다.
3) 함수호출에 의한 성능 저하가 일어나지 않으므로, 프로그램의 실행속도가 향상된다.
단점
1) 정확한 매크로 함수의 구현은 어려우며, 유지보수 또한 매우 어렵다.
2) 매크로 함수의 크기가 증가하면 증가할수록 괄호가 늘어나며 가독성이 떨어진다.
#과 ## 연산자
# 연산자
매크로 함수의 대체 리스트 안의 인수 앞에 사용하여 토큰을 문자열로 변환시켜준다. 해당 토큰은 실인수로 치환되면서 양쪽에 위치한 큰따옴표("")를 포함해 그대로 문자열 상수로 변환된다.
## 연산자
## 연산자는 두 개의 토큰을 하나의 토큰으로 결합해주는 전처리기 연산자이다. 변수나 함수의 이름을 미리 정의해둔 토큰과 동적으로 입력받은 토큰간 결합하여 변수명을 런타임에 정의할 수 있게 된다.
시스템 정의 매크로
C언어에서는 컴파일러가 참고해야할 정보를 알려주기 위해서 몇몇 매크로를 미리 정의하여 제공하고 있다.
사용시 선행처리 지시자로 정의하지 않아도 되지만, 사용자가 임의로 재정의할 수 는 없다.
#line
__LINE__ 매크로와 __FILE__ 매크로를 재정의할 수 있게 해준다. 라인 번호는 Int형 타입으로, 파일명은 문자열로 전달된다.
#erro
지정한 오류 메시지를 출력하고, 컴파일 과정을 중단시킨다. 지시어가 어떤 시스템에서 처리될 때 지시어에서 토큰은 오류 메시지로 출력되고, 전처리가 멈추고, 프로그램은 컴파일되지 않는다.
#pragma
정의된 실행 동작을 호출한다. 무시되는 실행에서 Pragma는 인식되지 않는다.
#undef
이미 정의되어 있는 매크로를 취소하는 동작을 수행한다.
가정 (assertion)
assert.h 헤더파일에서 정의된 assert 매크로는 결과값을 검사합니다. 만약 결과값이 0이면 assert는 오류 메시지를 출력하고 프로그램에서 실행을 종료하기 위해 abort 함수를 호출한다.