C++ 전처리기
전처리기는 실제 컴파일 전에 수행해야 하는 전처리에 대해 컴파일러에 지시하는 명령입니다.
모든 전처리기 지시문은 파운드 기호(#)로 시작하며 전처리기 지시문 앞에는 공백 문자만 나타날 수 있습니다. 전처리 지시문은 C++ 문이 아니므로 세미콜론(;)으로 끝나지 않습니다.
이전의 모든 예에는 #include 지시문이 있다는 것을 확인했습니다. 이 매크로는 헤더 파일을 소스 파일에 포함하는 데 사용됩니다.
C++에서는 #include, #define, #if, #else, #line 등과 같은 많은 전처리 명령어도 지원합니다. 이러한 중요한 명령어를 함께 살펴보겠습니다.
#define preprocessing
#define 전처리 지시문은 기호 상수를 만드는 데 사용됩니다. 이 기호 상수는 일반적으로 macro라고 하며 명령의 일반적인 형식은 다음과 같습니다.
#define macro-name replacement-text
이 코드 줄이 파일에 나타나면 프로그램이 컴파일되기 전에 파일의 모든 후속 매크로가 대체 항목으로 대체됩니다. 텍스트. 예:
#include <iostream> using namespace std; #define PI 3.14159 int main () { cout << "Value of PI :" << PI << endl; return 0; }
이제 이 코드를 테스트하고 전처리 결과를 살펴보겠습니다. 소스 코드 파일이 이미 존재한다고 가정하고 -E 옵션을 사용하여 결과를 컴파일하고 test.p로 리디렉션합니다. 이제 test.p 파일을 보면 이미 많은 정보가 포함되어 있는 것을 볼 수 있으며 파일 하단의 값이 다음과 같이 변경되었습니다.
$gcc -E test.cpp > test.p ... int main () { cout << "Value of PI :" << 3.14159 << endl; return 0; }
Function 매크로
를 사용할 수 있습니다. #define은 아래와 같이 매개변수 매크로를 사용하여 함수를 정의합니다.
#include <iostream> using namespace std; #define MIN(a,b) (((a)<(b)) ? a : b) int main () { int i, j; i = 100; j = 30; cout <<"The minimum is " << MIN(i, j) << endl; return 0; }
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.
The minimum is 30
조건부 컴파일
선택적으로 사용할 수 있는 몇 가지 명령이 있습니다. 프로그램 소스 코드의 일부를 컴파일합니다. 이 프로세스를 조건부 컴파일이라고 합니다.
조건부 전처리기의 구조는 if 선택 구조와 매우 유사합니다. 다음 전처리기 코드를 살펴보세요.
#ifndef NULL #define NULL 0 #endif
디버깅할 때만 컴파일할 수 있으며 디버그 스위치는 아래와 같이 매크로를 사용하여 구현할 수 있습니다.
#ifdef DEBUG cerr <<"Variable x = " << x << endl; #endif
기호가 #ifdef DEBUG 지시문 앞에 정의된 경우 상수 DEBUG 프로그램에서 cerr 문을 컴파일합니다. 다음과 같이 #if 0 문을 사용하여 프로그램의 일부를 주석 처리할 수 있습니다.
#if 0 不进行编译的代码 #endif
다음 예를 시도해 보겠습니다.
#include <iostream> using namespace std; #define DEBUG #define MIN(a,b) (((a)<(b)) ? a : b) int main () { int i, j; i = 100; j = 30; #ifdef DEBUG cerr <<"Trace: Inside main function" << endl; #endif #if 0 /* 这是注释部分 */ cout << MKSTR(HELLO C++) << endl; #endif cout <<"The minimum is " << MIN(i, j) << endl; #ifdef DEBUG cerr <<"Trace: Coming out of main function" << endl; #endif return 0; }
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.
Trace: Inside main function The minimum is 30 Trace: Coming out of main function
# 및 ## 연산자
# 및 ## 전처리기 연산자는 C++ 및 ANSI/ISO C에서 모두 사용할 수 있습니다. # 연산자는 대체 텍스트 토큰을 따옴표 붙은 문자열로 변환합니다.
아래 매크로 정의를 보세요:
#include <iostream> using namespace std; #define MKSTR( x ) #x int main () { cout << MKSTR(HELLO C++) << endl; return 0; }
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 나옵니다.
HELLO C++
어떻게 작동하는지 살펴보겠습니다. C++ 전처리기가 다음 행을
cout << MKSTR(HELLO C++) << endl;
행으로 변환한다는 것을 이해하는 것은 어렵지 않습니다.
cout << "HELLO C++" << endl;
## 연산자는 두 개의 토큰을 연결하는 데 사용됩니다. 예는 다음과 같습니다.
#define CONCAT( x, y ) x ## y
CONCAT이 프로그램에 나타나면 해당 인수가 연결되어 매크로 대신 사용됩니다. 예를 들어, 프로그램의 CONCAT(HELLO, C++)은 아래 예와 같이 "HELLO C++"로 대체됩니다.
#include <iostream> using namespace std; #define concat(a, b) a ## b int main() { int xy = 100; cout << concat(x, y); return 0; }
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 나옵니다.
100
어떻게 작동하는지 봅시다. C++ 전처리기가 다음 행을
cout << concat(x, y);
로 변환한다는 것을 이해하는 것은 어렵지 않습니다.
cout << xy;
C++의 미리 정의된 매크로
C++는 다음 표에 표시된 대로 몇 가지 미리 정의된 매크로를 제공합니다.
매크로 | 설명 |
---|---|
__LINE__ | 여기에는 프로그램이 컴파일될 때 현재 줄 번호가 포함됩니다. |
__FILE__ | 여기에는 프로그램이 컴파일될 때 현재 파일 이름이 포함됩니다. |
__DATE__ | 여기에는 소스 파일이 대상 코드로 변환된 날짜를 나타내는 월/일/년 형식의 문자열이 포함됩니다. |
__TIME__ | 여기에는 프로그램이 컴파일된 시간을 나타내는 시:분:초 형식의 문자열이 포함됩니다. |
위 매크로의 예를 살펴보겠습니다.
#include <iostream> using namespace std; int main () { cout << "Value of __LINE__ : " << __LINE__ << endl; cout << "Value of __FILE__ : " << __FILE__ << endl; cout << "Value of __DATE__ : " << __DATE__ << endl; cout << "Value of __TIME__ : " << __TIME__ << endl; return 0; }
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.
Value of __LINE__ : 6 Value of __FILE__ : test.cpp Value of __DATE__ : Feb 28 2011 Value of __TIME__ : 18:52:48