The source code of a C program can include various compilation directives called preprocessing commands. Although they are not actually part of the C language, they extend the context of C programming. This section describes how to apply preprocessor and annotations to streamline the program development process and improve the readability of the program. The ANSI standard-defined C language preprocessor includes the following commands:
#define, #error, # include, #if, #else, #elif, #endif, #ifdef, #ifndef, #undef, #line, #pragma等. It is very obvious that all pre-processing commands are preceded by the symbol #, which is described separately below.
A #define
The command # define defines an identifier and a string. Each time the identifier is encountered in the source program, it is substituted with the defined string. The ANSI standard defines an identifier as a macro name and replaces the replacement process with a macro substitution. The general form of the command is:
#define Identifier string
Attention:
1 The statement has no semicolon. There can be any space between the identifier and the string, and once the string starts, it ends with a new line.
2 once the macro name is defined, it can become part of another macro name definition.
3 A macro substitution is simply a text string instead of a macro identifier, provided that the macro identifier must be identified independently or not replaced. For example:
#define XYZ This is a TES
Use macro printf ("xyz");//The segment does not print "This is a test" and prints "xyz". Because the precompiled compiler recognizes "XYZ"
4 if the string is longer than one row, you can continue with a backslash ' \ ' at the end of the line.
#defineLONG_STRING "This is a very long\
String that's used as an example "
5 C language programs generally use uppercase letters to define identifiers.
6 one of the great benefits of replacing a real function with a macro substitution is that macro substitution increases the speed of the code because there is no overhead for function calls. But increasing the speed also has a price: The program length is increased due to repeated coding.
Two #error
Command #error force the compiler to stop compiling, mainly for program debugging.
#error指令使预处理器发出一条错误消息, the message contains the text in the instruction. The purpose of this instruction is to give certain information before the program crashes.
three #include
The command #i nclude causes the compiler to embed another source file with an # include source file, and the source file that is being read in must be enclosed in double or angle brackets. For example:
# include "Stdio.h" or # include
Both lines of code use the C compiler to read in and compile the subroutine used to process the disk file library.
It is possible to embed a file within a file in the #i nclude command, which is called a nested embedded file, and the nesting hierarchy is dependent on the specific implementation.
If the explicit path name is part of the file identifier, only those subdirectories are searched for the embedded file. Otherwise, if the file name is enclosed in double quotation marks, the current working directory is retrieved first. If no files are found, search in all directories described on the command line. If the file is still not found, search for the standard directory defined when the implementation is implemented.
If you do not have an explicit pathname and the file name is surrounded by angle brackets, it is first retrieved from the directory in the compilation command line. If the file is not found, the standard directory is retrieved and the current working directory is not retrieved .
Four conditional compilation commands
There are several commands that can be selectively compiled for each part of the program's source code, which is called conditional compilation. Commercial software companies widely apply conditional compilation to provide and maintain many customer versions of a program.
#if , #else, #elif及 #endif
If the constant expression after #if的一般含义是如果 # if is true, the code between it and #endif is compiled, otherwise the code is skipped. The command #endif identifies the end of an # if block.
#if constant-expression
Statement sequence
#endif
Eg:
#define MAX 91
#include
using namespace Std;
int main ()
{
#if MAX > 99
cout<< "MAX is bigger than" <
#elif MAX > 90
cout<< "MAX is bigger than" <
#else
cout<< "MAX is smaller than" <
#endif
return 0;
}
An expression that follows # if is evaluated at compile time, so it must contain only constants and identifiers that are already defined, and cannot use variables. The expression is not allowed to contain the operator sizeof (sizeof is also a compile-time evaluation).
#else命令的功能有点象C语言中的else; #else建立另一选择 (in the case of # if failure). Note that the #else属于 # if block.
#elif command meaning and else IF the same, it forms an if else-if ladder-like statement, which can make a variety of compilation choices. #elif followed by a constant expression. If the expression is true, the subsequent code block is compiled, and no other #elif expression is tested. Otherwise, test the next piece sequentially.
#if expression
Statement sequence
#elif expression1
Statement sequence
#endif
In nested conditional compilation, #endif, #else或 #elif match the most recent # if or #elif.
# ifdef and # ifndef
Another way to conditionally compile is to use the #ifdef and #ifndef commands, which represent "if there is a definition" and "if there is no definition" respectively. # The general form of ifdef is:
# ifdef macroname
Statement sequence
#endif
#ifdef与 #ifndef can be used for # if, #else, #elif语句中, but must be associated with a #endif.
#define MAX 91
#include
using namespace Std;
int main ()
{
#ifdef MAX
cout<< "hello,max!" <
#else
cout<< "Where is MAX?" <
#endif
#ifndef LEO
cout<< "LEO is not defined" <
#endif
return 0;
}
Command #undef cancels the definition of a macro name that was previously defined. The general form is:
#undef macroname
The command #line changes the contents of __line__ and __file__ , which are pre-defined identifiers in the compilation program. The basic form of the command is as follows:
#line number["filename"]
Where the number is any positive integer, the optional file name is any valid file identifier. The line number is the current line number in the source program, and the file name is the name of the source file. Command #line is mainly used for debugging and other special applications. Note: The number after #line identifies the digital ID that starts on the next line .
#line "Jia"
cout<< "#line Change line and filename!" <
cout<<__line__<
cout<<__file__<
Five #pragma
Command #pragma a command that is defined when implemented, which allows a variety of instructions to be passed to the compiler.
The role of
#pragma is to set the state of the compiler or instruct the compiler to complete some specific actions. #pragma directives give a method to each compiler in the hold with c and c++ language is fully compatible The gives features that are proprietary to the host or operating system. According to the definition compilation instructions are machine or operating system proprietary and is different for each compiler.
is generally formatted as : #Pragma Para
1 message parameter.
&NBSP; message parameter to output the appropriate information in the Compile Information Output window , which is very important for controlling the source code information. It is used by
message text Prints the message text in the Compile Output window when the compiler encounters this instruction.
When we define a number of macros in the program to control the source code version, it is possible for us to forget that we have the correct settings for these macros, and we can use this instruction to check at compile time. Suppose we want to determine whether we have defined the _x86 this macro can use the following method
#ifdef _x86
#pragma message ("_x86 macro activated!")
#endif
When we define _x86 this macro, the application will display the "_
X86 macro activated!" . We will not scratching because we do not remember some of the specific macros we have defined.
2 code_seg parameter.
Format such as:
#pragma code_seg (["Section-name" [, "Section-class"]])
it The is able to set code snippets for function code stored in the program , which is used when we develop the driver.
3 #pragma once ( more commonly used)
you can guarantee that the header file will be compiled once, as long as you add this directive at the very beginning of the header file. This instruction is actually in vc6 , but it is not much used because of compatibility.
4 #pragma hdrstop
This means that the precompiled header file ends, and the subsequent header files are not precompiled. BCB can precompile the header file to speed up the link, but if all the header files are precompiled and may take up too much disk space, use this option to exclude some header files.
Sometimes there are dependencies between units, such as cell a depends on unit b, so unit b is compiled before unit a . You can use #pragma startup to specify the compilation priority, and if you use #pragma package (smart_init) , theBCB will be compiled according to the priority size.
5 #pragma resource "*.DFM"
Indicates that the resources in the *.DFM file are added to the project. The *.dfm includes the definition of the form's appearance.
6 #pragma warning (disable:4507; once:4385; error:164)
Equivalent to:
#pragma warning (disable:4507)/*does not display4507and the thewarning message. If the compile time always appears4507Number Warning and theNumber Warning, You can use this directive if you think there is no mistake.*/
#pragma warning (once:4385)//4385 warning information is only reported once
#pragma warning (error:164)// put164warning message as an error.
And thispragma warningThe following formats are also supported:
#pragma warning (push [, N])
#pragma warning (POP)
Over hereNRepresents a warning level(1---4)。
#pragma warning (push)The existing warning state that holds all warning messages.
#pragma warning (push, n) saves the existing warning state of all warning messages and sets the global warning level toN.
#pragma warning (pop) pops the last warning message to the stack and cancels all changes made between the stack and the stack. For example:
#pragma warning (push)
#pragma warning (disable:4705)
#pragma warning (disable:4706)
#pragma warning (disable:4707)
//.......
#pragma warning (POP)
At the end of this code, re-save all the warning messages(Including4705,4706And4707)。
7 pragma comment (...)
This directive places a note record into an object file or executable file.
Used inLibKeyword to help us connect to a library file.
8 Progma Pack(N)
Specifies how the structure is aligned. #pragma pack (n) to set the variable to n -byte alignment.
N byte alignment means that the offset of the starting address at which the variable is stored is in two cases:
First, if N is greater than or equal to the number of bytes consumed by the variable, the offset must satisfy the default alignment.
Second, if N is less than the number of bytes consumed by the type of the variable, then the offset is N without satisfying the default alignment.
The total size of the structure also has a constraint, divided into the following two conditions: if N is greater than the number of bytes occupied by all member variable types, the total size of the structure must be a multiple of the amount of space occupied by the variable occupying the largest space; Otherwise, you must provide N the multiple.
The following examples illustrate their usage.
#pragma pack (push)// Save alignment status
#pragma pack (4)// set to 4 -byte alignment
struct test
{
Char M1;
Double M4;
int m3;
};
#pragma pack (POP)// Restore alignment status
To test this feature, you can use sizeof() to test the length of the struct body!
C Language Preprocessing Command summary