C 언어 전처리 명령 정보
C 프로그램의 소스 코드에는 전처리 명령이라고 불리는 다양한 컴파일 명령이 포함될 수 있습니다. 실제로 C 언어의 일부는 아니지만 C 프로그래밍 환경을 확장합니다. 이 섹션에서는 프로그램 개발 프로세스를 단순화하고 프로그램 가독성을 향상시키기 위해 전처리기와 주석을 적용하는 방법을 설명합니다. ANSI 표준에 의해 정의된 C 언어 전처리기에는 다음 명령이 포함됩니다:
#define, #error, #include, #if, #else, #elif, #endif, #ifdef, #ifndef, #undef , #line, #pragma 등 모든 전처리 명령은 아래에 소개된 기호 #으로 시작한다는 것이 매우 분명합니다.
One #define
#define 명령은 식별자와 문자열을 정의합니다. 소스 프로그램에서 이 식별자를 발견할 때마다 정의된 문자열로 대체됩니다. ANSI 표준은 식별자를 매크로 이름으로 정의하고 교체 프로세스 매크로 교체를 호출합니다. 명령의 일반적인 형식은 다음과 같습니다.
#define 식별자 문자열
참고:
1 이 명령문에는 세미콜론이 없습니다. 식별자와 문자열 사이에는 공백이 있을 수 있습니다. 문자열이 시작되면 새 줄로만 끝납니다.
2 매크로 이름이 정의된 후에는 다른 매크로 이름 정의의 일부가 될 수 있습니다.
3 매크로 교체는 매크로 식별자가 독립적으로 식별되어야 하는 경우에만 매크로 식별자를 텍스트 문자열로 교체합니다. 그렇지 않으면 교체가 수행되지 않습니다. 예:
#define XYZ 이것은 테스트입니다.
매크로 사용 printf("XYZ"); //이 단락은 "이것은 테스트입니다"를 인쇄하지 않지만 "XYZ"를 인쇄합니다. ". 프리컴파일러는 "XYZ"를 인식하기 때문에
4 문자열이 한 줄보다 길면 줄 끝에 백슬래시 '\'를 사용하여 줄을 계속할 수 있습니다.
#defineLONG_STRING"예로 사용되는 매우 긴\
문자열입니다."
5 C 언어 프로그램은 일반적으로 식별자를 정의하기 위해 대문자를 사용합니다.
6 실제 함수 대신 매크로 대체를 사용하면 큰 이점은 매크로 대체를 사용하면 함수 호출에 따른 오버헤드가 없기 때문에 코드 속도가 빨라진다는 것입니다. 그러나 속도 증가에는 대가가 따릅니다. 즉, 반복되는 인코딩으로 인해 프로그램 길이가 늘어납니다.
두 개의 #error
#error 명령은 컴파일러가 컴파일을 중지하도록 강제하며 주로 프로그램 디버깅에 사용됩니다.
#error 지시문은 전처리기가 지시문의 텍스트를 포함하는 오류 메시지를 발행하도록 합니다. 이 지시문의 목적은 프로그램이 충돌하기 전에 특정 정보를 제공하는 것입니다.
세 개의 #include
#i nclude 명령은 컴파일러가 #include를 사용하여 다른 소스 파일을 소스 파일에 포함하도록 합니다. 읽을 소스 파일은 큰따옴표로 묶어야 합니다. 또는 괄호 안에 큰 따옴표를 붙입니다. 예:
#include "stdio.h" 또는 #include
두 코드 줄 모두 읽고 C 컴파일러를 사용하여 컴파일하여 디스크 파일 라이브러리를 처리합니다. .서브루틴.
#i nclude 명령을 사용하면 파일 내에 파일을 포함할 수 있습니다. 이 방법을 중첩 포함 파일이라고 합니다. 중첩 수준은 특정 구현에 따라 다릅니다.
명시적인 경로 이름이 파일 식별자의 일부인 경우 해당 하위 디렉터리에서만 포함된 파일을 검색합니다. 그렇지 않고 파일 이름을 큰따옴표로 묶으면 현재 작업 디렉터리가 먼저 검색됩니다. 파일을 찾을 수 없으면 명령줄에 지정된 모든 디렉터리를 검색합니다. 여전히 파일을 찾을 수 없으면 구현에 의해 정의된 표준 디렉터리가 검색됩니다.
명시적인 경로 이름이 없고 파일 이름이 꺾쇠 괄호로 묶인 경우 컴파일 명령줄의 디렉터리가 먼저 검색됩니다. 파일을 찾을 수 없으면 표준 디렉터리를 검색하고 현재 작업 디렉터리는 검색하지 않습니다.
4가지 조건부 컴파일 명령
프로그램 소스 코드의 다양한 부분을 선택적으로 컴파일할 수 있는 여러 명령이 있습니다. 이 프로세스를 조건부 컴파일이라고 합니다. 조건부 컴파일은 상용 소프트웨어 회사에서 다양한 고객 버전의 프로그램을 제공하고 유지 관리하기 위해 널리 사용됩니다.
#if, #else, #elif 및 #endif
#if의 일반적인 의미는 #if 뒤의 상수 표현식이 true이면 이를 컴파일하고 #endif 코드를 작성하고, 그렇지 않으면 해당 코드를 건너뜁니다. #endif 명령은 #if 블록의 끝을 표시합니다.
#if 상수 표현식
문 순서
#endif
예:
#define MAX 91
#include
네임스페이스 std 사용;
int main()
{
# if MAX > 99
cout<<"MAX는 99보다 큽니다."< #elif MAX > 90 cout<<"MAX는 99보다 큽니다. 90보다 큼"< #else cout<<"MAX는 90보다 작습니다"< #endif return 0; } #if 뒤에 오는 표현식은 컴파일 타임에 평가되므로 상수만 포함해야 하며 정의된 식별자는 사용할 수 없습니다. 표현식에는 연산자 sizeof가 포함되어서는 안 됩니다. sizeof는 컴파일 타임에도 평가됩니다. #else 명령은 C 언어의 else와 약간 유사하게 작동합니다. #else는 다른 옵션을 만듭니다(#if 실패할 경우). #else는 #if 블록에 속합니다. #elif 명령의 의미는 ELSE IF와 동일하며 다양한 컴파일 선택을 할 수 있는 if else-if 래더 문을 구성합니다. #elif 뒤에는 상수 표현식이 옵니다. 식이 true이면 다음 코드 블록이 컴파일되고 다른 #elif 식은 테스트되지 않습니다. 그렇지 않으면 다음 블록이 순차적으로 테스트됩니다. #if 표현식 문 순서 #elif 표현식1 문 순서 #endif 중첩 조건부 컴파일에서 #endif, #else 또는 #elif는 가장 가까운 #if 또는 #elif와 일치합니다. # ifdef 및 # ifndef 조건부 컴파일의 또 다른 방법은 "정의가 있는 경우" 및 "정의가 없는 경우"를 나타내는 #ifdef 및 #ifndef 명령을 사용하는 것입니다. 정의"라고 각각 설명합니다. # ifdef의 일반적인 형식은 다음과 같습니다: # ifdef 매크로 이름 문 순서 #endif #ifdef 및 #ifndef는 다음과 같습니다. #if, #else, #elif 문을 사용했지만 #endif와 함께 사용해야 합니다. #define MAX 91 #include 네임스페이스 std 사용; int main() { #ifdef MAX cout<<"안녕, MAX!"< #else cout <<"MAX는 어디에 있나요?"< #endif #ifndef LEO cout<<"LEO가 정의되지 않았습니다."< #endif return 0; } #undef 명령은 이전에 정의된 매크로 이름 정의를 취소합니다. 일반적인 형식은 다음과 같습니다. #undef 매크로 이름 #line 명령은 컴파일러에 미리 정의된 식별자인 __LINE__ 및 __FILE__의 내용을 변경합니다. 명령의 기본 형식은 다음과 같습니다. #line number["filename"] 숫자는 양의 정수이고 선택적 파일 이름은 유효한 파일 식별자입니다. 줄 번호는 소스 프로그램의 현재 줄 번호이고, 파일 이름은 소스 파일의 이름입니다. 명령 #line은 주로 디버깅 및 기타 특수 응용 프로그램에 사용됩니다. 참고: #line 뒤의 숫자는 다음 줄부터 시작하는 숫자를 나타냅니다. #line 100 "jia" cout<<"#line 줄과 파일 이름을 변경하세요!"< cout<< __LINE__< cout<<__FILE__< 五#pragma #pragma 명령은 구현 중에 정의됩니다. 다양한 명령을 컴파일러에 전달할 수 있는 명령입니다. #pragma의 기능은 컴파일러의 상태를 설정하거나 컴파일러에게 특정 작업을 완료하도록 지시하는 것입니다. #pragma 지시문은 각 컴파일러가 C 및 C++ 언어와의 완전한 호환성을 유지하면서 호스트 또는 운영 체제별 기능을 제공하는 방법을 제공합니다. 정의에 따르면 pragma는 특정 컴퓨터 또는 운영 체제이며 각 컴파일러마다 다릅니다. 형식은 일반적으로 #Pragma Para 1 메시지 매개변수입니다. Message 매개변수는 컴파일 정보 출력 창에 해당 정보를 출력할 수 있으며 이는 소스 코드 정보 제어에 매우 중요합니다. 사용 방법은 다음과 같습니다. #pragma message("Message text") 컴파일러가 이 명령어를 발견하면 컴파일 출력 창에 메시지 텍스트를 인쇄합니다. 소스 코드 버전을 제어하기 위해 프로그램에 많은 매크로가 정의되어 있으면 이러한 매크로를 올바르게 설정했는지 잊어버릴 수 있습니다. 이 경우 컴파일 중에 이 명령을 사용하여 확인할 수 있습니다. 소스 코드 어딘가에 _X86 매크로를 정의했는지 확인하려면 다음 방법을 사용할 수 있습니다. #ifdef _X86 #pragma message(“_X86 매크로가 활성화되었습니다! ” ) #endif _X86 매크로가 정의되면 응용 프로그램은 "컴파일이 활성화될 때 컴파일 출력 창에 X86 매크로를 표시합니다!" . 정의한 특정 매크로가 기억나지 않는다고 해서 머리를 긁적일 일은 없을 것입니다. 2 code_seg 매개변수. 다음과 같은 형식: #pragma code_seg( ["section-name"[,"section-class"] ] ) 다음에서 기능을 설정할 수 있습니다. 프로그램 코드가 저장된 코드 세그먼트는 드라이버를 개발할 때 사용됩니다. 3 #pragma Once(더 일반적으로 사용됨) 이 명령을 헤더 파일 시작 부분에 추가하면 헤더 파일이 한 번만 컴파일되도록 할 수 있습니다. 이 명령어는 실제로 VC6에 이미 존재하지만 호환성을 고려하면 많이 사용되지는 않습니다. 4 #pragma hdrstop 미리 컴파일된 헤더 파일이 여기서 끝나고 후속 헤더 파일은 미리 컴파일되지 않음을 나타냅니다. BCB는 링크 속도를 높이기 위해 헤더 파일을 미리 컴파일할 수 있지만 모든 헤더 파일을 미리 컴파일하면 너무 많은 디스크 공간을 차지할 수 있으므로 이 옵션을 사용하여 일부 헤더 파일을 제외할 수 있습니다. 때때로 유닛 간에 종속성이 있는 경우가 있습니다. 예를 들어 유닛 A는 유닛 B에 종속되므로 유닛 A보다 먼저 유닛 B를 컴파일해야 합니다. #pragma 시작을 사용하여 컴파일 우선순위를 지정할 수 있습니다. #pragma 패키지(smart_init)를 사용하면 우선순위에 따라 BCB가 순차적으로 컴파일됩니다. 5 #pragma Resource "*.dfm" *.dfm 파일의 리소스를 프로젝트에 추가함을 나타냅니다. *.dfm에는 양식 모양 정의가 포함됩니다. 6 #pragma warning( 비활성화 : 4507 34; 한 번 : 4385; 오류 : 164 ) 다음과 동일: #pragma warning(disable:4507 34 ) /* 경고 메시지 4507 및 34를 표시하지 않습니다. 컴파일 시 경고번호 4507번과 경고번호 34번이 항상 발생하고, 당연히 에러가 없을 것이라고 생각한다면 이 명령어를 사용하면 됩니다. */ #pragma warning(once:4385) // 4385번 경고 메시지는 한 번만 보고됩니다. #pragma warning(error:164) // 4385번 경고 메시지를 처리합니다. 164 실수네요. 동시에 이 pragma 경고는 다음 형식도 지원합니다: #pragma warning( push [ ,n ] ) #pragma warning( pop ) 여기서 n은 경고 수준(1---4)을 나타냅니다. #pragma warning( push )는 모든 경고 메시지의 기존 경고 상태를 저장합니다. #pragma warning( push, n)은 모든 경고 메시지의 기존 경고 상태를 저장하고 전역 경고 수준을 n으로 설정합니다. #pragma warning( pop )은 마지막 경고 메시지를 스택에 팝하고 푸시와 팝 사이에 이루어진 모든 변경 사항이 취소됩니다. 예: #pragma warning( push ) #pragma warning( 비활성화 : 4705 ) #pragma warning( 비활성화 : 4706 ) #pragma warning( 비활성화 : 4707 ) //....... #pragma warning( pop ) 이 코드에서 마지막으로 모든 경고 메시지(4705, 4706 및 4707 포함)를 다시 저장하십시오. 7 pragma comment(...) 이 명령어는 주석 레코드를 개체 파일이나 실행 파일에 넣습니다. 일반적으로 사용되는 lib 키워드는 라이브러리 파일을 연결하는 데 도움이 될 수 있습니다. 8 progma pack(n) 구조 정렬을 지정합니다. #pragma pack(n) - 변수를 n바이트 정렬로 설정합니다. n 바이트 정렬은 변수가 저장되는 시작 주소의 오프셋에 대해 두 가지 상황이 있음을 의미합니다. 첫째, n이 바이트 수보다 크거나 같은 경우 변수가 점유하는 경우 오프셋은 기본 정렬을 충족해야 합니다. 두 번째로, n이 변수 유형이 차지하는 바이트 수보다 작으면 오프셋은 n의 배수이므로 필요하지 않습니다. 기본 정렬 방식을 충족합니다. 구조체의 전체 크기에도 제약이 있는데, 이는 다음 두 가지 상황으로 나눌 수 있습니다. n이 모든 멤버 변수 유형이 차지하는 바이트 수보다 큰 경우 전체 크기는 구조체는 가장 큰 공간을 차지하는 변수가 차지해야 합니다. 그렇지 않으면 n의 배수여야 합니다. 다음 예에서는 사용법을 보여줍니다. #pragma pack(push) //정렬 상태 저장 #pragma pack(4)//4바이트 정렬로 설정 struct test p> { 문자 m1; 더블 m4; int m3; }; #pragma pack(pop)//정렬 상태 복원 이 기능을 테스트하려면 sizeof()를 사용하여 구조의 길이를 테스트할 수 있습니다!