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