C language learning - preprocessing command

1. Introduction to preprocessing commands
A C language program begins with #, and a line ending with a newline character is called a preprocessing directive, which includes:
1) Macro definition: #define #undef
2) The file includes: #include
3) Conditional compilation: #if #ifdef #else #elif #endif
4) Other: #line #error #pragam

2. Macro definition
1) Classification: macro definition with parameters, macro definition without parameters
2) Without parameter macro definition:
1 form: #define identifier (macro name) word string (macro body), do not add ";" at the end
2 Function: Replace the identifier in the program with the macro body
3 Note:
a. For general macro names Capital letters indicate where in the program the substitution is easy to find
b. When the word string If it is too long, you can add "\" at the end, that is, use the backslash continuation character , for example:
#define LONG_STRING "this is a very long string that is\
used as an example"
c. The scope of the macro name is: from It starts from the definition to the end of the file where it is located , not necessarily in the main function
d. Macro definition Definitions can be nested , for example:
#define R 2.0
#define L 2*R, this is correct.
e. But Recursive definitions are not allowed , as shown above: #define R 2.0+R
The string constants in the program are the characters in double quotation marks, and are not used as macros for macro substitution , such as:
#define XYZ 2.0
printf("XYZ"),此时输出的是XYZ,而不是2.0
f. 宏可以被 重复定义
#define N 10
结束;
#define N 20
结束;
g. 在宏定义中,如果单词串是个 表达式,那么一定要用括号括起来
h.#define TM_B 是个标准正确的宏定义
3)带参数宏定义:
1形式: #define 标识符(参数列表) 单词串
标识符是宏名,一般也用大写字母表示
参数表有一个或多个参数构成,参数只有参数名,没有数据类型符,参数之间用逗号隔开
单词串是宏的内容文本,通常引用宏的参数
2预编译过程:
首先将宏内容文本中的宏参数换成实参文本,这样形成了宏的实际内容文本,再将这个宏的实际内容文本替换源程序中的宏标识符。
3注意:宏名与圆括号之间 不能有空白符,否则就会变成定义一个不带参数的宏,而要替换的内容是空白符之后所有的字符。
在宏替换中,替换文本中如果出现预处理器运算符##,则该参数将被实参替换且##与前后空白符将被删除,如:
#define paste(front,back) front ## back。
由于参数的宏在使用时,参数大多是表达式,宏内容本身也是表达式,因此,不但需要将整个宏括起来,还要讲宏参数括起来,否则有意想不到的结果,如:
#define SORT(x) x * x
3.文件包含
1)形式 #include <> 或者 #include “包含文件名”
2)两种表示的区别:
<>:直接到系统指定的“文件包含目录”去查找被包含的文件。
“”:系统首先到当前目录下查找被还包含文件,如果没找到,再到系统中指定的“文件包含目录”去查找
3)注意:
文件包含 可以嵌套,即被包含文件中有包含另一个文件。

4.条件编译
1)定义及作用:根据一定条件去编译源文件的不同部分,这就是条件编译。
条件编译使得统一源程序在不同的编译条件下得到不同的目标代码。
2)#if.....#endif形式:
a.格式:#if 条件1 (条件必须为常量表达式,通常会用到宏名,条件可以不加括号)
程序段1
#elif 条件2 ( 可以没有
程序段2
...
#else ( 可以没有
程序段n
#endif( 必须存在)
3)#ifdef....#endif形式:
a.格式:#ifdef 宏名 (含义:是否定义了宏名)
程序段1
#else 宏名
程序段n
#endif
4)#ifndef...#endif
a.格式:#ifndef 宏名 (含义:如果没有被宏定义)
程序段1
#else
程序段2
#endif
5)注意:
条件编译与分支语句不一样:条件编译是程序运行前的预处理
分支语句是程序运行时的处理
条件编译的条件必须是常量表达式,如:
#define N 10
int NUM=10;
#if NUM==10 (这里是错误的,NUM是变量,不是常量表达式)
...
条件编译命令可以放在所有函数的外部,也可以放在函数内部
6)好处:
条件编译解决了一个程序放在不同环境运行编译的问题,例如,列出所有条件,在不同环境中只需要在程序开头打上#define ... 则可以在这个环境中使用

7)总结:
a.宏定义时末尾不加分号
b.宏扩展的整体和参数一般用括号括起来。
c.在用宏来定义字符串常量时,没有用引号。
d.条件编译的条件必须是常量。






































Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325805379&siteId=291194637