C 전처리기
C 전처리기 는 컴파일러의 일부가 아니지만 컴파일 프로세스에서 별도의 단계입니다. 간단히 말해서, C 전처리기는 실제 컴파일 전에 필요한 전처리를 완료하도록 컴파일러에 지시하는 텍스트 교체 도구에 지나지 않습니다. C Preprocessor를 CPP로 줄여서 설명하겠습니다.
모든 전처리기 명령은 파운드 기호(#)로 시작합니다. null이 아닌 첫 번째 문자여야 하며 가독성을 높이기 위해 전처리기 지시문은 첫 번째 열에서 시작해야 합니다. 모든 중요한 전처리기 지시어는 다음과 같습니다.
지시어 | 설명 |
---|---|
#define | 매크로 정의 |
#include | 소스 코드 파일 포함 |
#undef | 취소 정의된 매크로 |
#ifdef | 매크로가 이미 정의된 경우 true를 반환합니다. |
#ifndef | 매크로가 정의되지 않은 경우 true를 반환합니다. |
#if | if 주어진 조건이 true인 경우 , 다음 코드를 컴파일하세요 |
#else | #if 대안 |
#elif | 이전 #if 주어진 조건이 true가 아니고 현재 조건이 true인 경우 다음 코드를 컴파일하세요 |
#endif | #if...#else 조건부 컴파일 블록 종료 |
#error | 표준 오류가 발생하면 오류 메시지 출력 |
#pragma | 정규화 방법을 사용하여 컴파일러 컴파일러에 특수 명령을 실행합니다 |
전처리기 예제
다음 예제를 분석하여 다양한 지침을 이해하세요.
#define MAX_ARRAY_LENGTH 20
이 명령은 CPP에 모든 MAX_ARRAY_LENGTH를 20으로 바꾸도록 지시합니다. 가독성을 높이기 위해 #define을 사용하여 상수를 정의하세요.
#include <stdio.h>#include "myheader.h"
이 지침은 CPP에게 시스템 라이브러리에서 stdio.h를 가져와 현재 소스 파일에 텍스트를 추가하도록 지시합니다. 다음 줄은 CPP에게 로컬 디렉터리에서 myheader.h를 가져와 현재 소스 파일에 내용을 추가하도록 지시합니다.
#undef FILE_SIZE#define FILE_SIZE 42
이 명령은 정의된 FILE_SIZE를 취소하고 42로 정의하도록 CPP에 지시합니다.
#ifndef MESSAGE #define MESSAGE "You wish!"#endif
이 지시문은 MESSAGE가 정의되지 않은 경우에만 MESSAGE를 정의하도록 CPP에 지시합니다.
#ifdef DEBUG /* Your debugging statements here */#endif
이 지시문은 DEBUG가 정의된 경우 처리 문을 실행하도록 CPP에 지시합니다. 이 지시문은 컴파일 타임에 -DDEBUG 스위치를 gcc 컴파일러에 전달하는 경우 유용합니다. 이는 DEBUG를 정의하며 컴파일 중에 언제든지 디버깅을 켜거나 끌 수 있습니다.
사전 정의된 매크로
ANSI C는 많은 매크로를 정의합니다. 프로그래밍에 이러한 매크로를 사용할 수 있지만 미리 정의된 매크로를 직접 수정할 수는 없습니다.
Macro | Description |
---|---|
__DATE__ | 현재 날짜, "MMM DD YYYY" 형식으로 표현되는 문자 상수입니다. |
__TIME__ | 현재 시간, "HH:MM:SS" 형식으로 표현되는 문자 상수입니다. |
__FILE__ | 여기에는 현재 파일 이름, 문자열 상수가 포함됩니다. |
__LINE__ | 여기에는 현재 줄 번호, 즉 십진수 상수가 포함됩니다. |
__STDC__ | 컴파일러가 ANSI 표준으로 컴파일하는 경우 1로 정의됩니다. |
다음 예를 시도해 보겠습니다.
#include <stdio.h>main(){ printf("File :%s\n", __FILE__ ); printf("Date :%s\n", __DATE__ ); printf("Time :%s\n", __TIME__ ); printf("Line :%d\n", __LINE__ ); printf("ANSI :%d\n", __STDC__ );}
위 코드(test.c 파일에 있음)를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.
File :test.cDate :Jun 2 2012Time :03:36:24Line :8ANSI :1
전처리기 연산자
C 전처리기 프로세서는 다음과 같은 연산자를 제공합니다. 매크로 생성을 도와주세요:
매크로 연속 연산자 ()
매크로는 일반적으로 한 줄에 작성됩니다. 그러나 매크로가 너무 길어서 한 줄에 다 들어갈 수 없다면 매크로 연속 연산자()를 사용하세요. 예:
#define message_for(a, b) \ printf(#a " and " #b ": We love you!\n")
문자열 상수화 연산자(#)
매크로 정의에서 매크로 매개변수를 문자열 상수로 변환해야 하는 경우 문자열 상수화 연산자(#)가 사용됩니다. 매크로에 사용되는 이 연산자에는 특정 인수 또는 인수 목록이 있습니다. 예:
#include <stdio.h>#define message_for(a, b) \ printf(#a " and " #b ": We love you!\n")int main(void){ message_for(Carole, Debra); return 0;}
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.
Carole and Debra: We love you!
태그 붙여넣기 연산자(##)
매크로 정의 내의 태그 붙여넣기 연산자(##)는 두 매개 변수를 병합합니다. 두 개의 독립적인 태그를 매크로 정의에서 하나의 태그로 결합할 수 있습니다. 예:
#include <stdio.h>#define tokenpaster(n) printf ("token" #n " = %d", token##n)int main(void){ int token34 = 40; tokenpaster(34); return 0;}
위 코드를 컴파일하고 실행하면 다음 결과가 생성됩니다.
token34 = 40
이 예제가 컴파일러에서 다음과 같은 실제 출력을 생성하기 때문에 이런 일이 발생합니다.
printf ("token34 = %d", token34);
이 예제에서는 토큰##n을 보여줍니다. 문자열 상수화 연산자(#)와 토큰 붙여넣기 연산자(##)를 사용하는 token34로 연결됩니다.
define() 연산자
전처리기 define 연산자는 식별자가 #define을 사용하여 정의되었는지 확인하기 위해 상수 표현식에 사용됩니다. 지정된 식별자가 정의된 경우 값은 true(0이 아님)입니다. 지정된 식별자가 정의되지 않은 경우 값은 false(0)입니다. 다음 예에서는 정의된() 연산자의 사용법을 보여줍니다.
#include <stdio.h>#if !defined (MESSAGE) #define MESSAGE "You wish!"#endifint main(void){ printf("Here is the message: %s\n", MESSAGE); return 0;}
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.
Here is the message: You wish!
매개변수화된 매크로
CPP 강력한 기능은 매개변수화된 매크로를 사용하는 기능입니다. 기능을 시뮬레이션합니다. 예를 들어, 다음 코드는 숫자의 제곱을 계산합니다.
int square(int x) { return x * x;}
다음과 같이 매크로를 사용하여 위 코드를 다시 작성할 수 있습니다.
#define square(x) ((x) * (x))
매개변수가 있는 매크로를 사용하기 전에 #define 지시어를 사용하여 정의해야 합니다. 매개변수 목록은 괄호로 묶여 있으며 매크로 이름 바로 뒤에 와야 합니다. 매크로 이름과 여는 괄호 사이에는 공백이 허용되지 않습니다. 예:
#include <stdio.h>#define MAX(x,y) ((x) > (y) ? (x) : (y))int main(void){ printf("Max between 20 and 10 is %d\n", MAX(10, 20)); return 0;}
위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.
Max between 20 and 10 is 20