1.预处理指令
(1)预定义符号
(2) #define定义常量
(3)#define定义宏
(4)带副作用的宏参数
(5)宏与函数的对比
2.#和##
(1)#运算符
(2)##运算符
3.#undef
4.条件编译
一.预处理指令
1.预处理的介绍:
预处理是指在C语言源代码被编译之前,由预处理程序对源代码进行的一系列处理过程。这些处理包括宏定义、文件包含和条件编译等,主要目的是为了提高代码的移植性和修改的方便性
预处理的具体功能
宏定义:通过#define指令定义宏,可以在程序中用特定的标识符代替一段代码,方便代码的重用和修改
文件包含:使用#include指令将其他文件的内容插入到当前文件中,常用于包含头文件,提供函数声明和宏定义等
条件编译:通过#ifdef、#ifndef、#endif等指令根据条件编译不同的代码段,常用于调试信息的添加和移除
总而言之: 预处理就是编译和链接过程中的一个阶段。在预处理阶段,源文件和头文件都会被处理成.i为后缀的文件,预处理阶段主要是处理那些源文件中以#开头的预处理指令
2.预处理指令:
(1)预定义符号:
(ps:_STDC_无法在vs里使用)
举个例子:
(2)#define定义常量:
具体使用:特别注意(define定义常量不要在末尾加上”;“)
否则:
(3)#define定义宏:
具体使用及注意事项:
(4)带副作用的宏参数:
宏相对于函数的优势:
1.在进行简单运算时,宏所需的时间和代码规模上更胜一筹。
2.宏对于参数类型没有限制,而函数限制参数类型
函数相对于宏的优势:
1.函数相对于宏更方便调试
2.函数可以递归,宏不可以递归
3.函数的结果更容易预料,宏存在带副作用参数和操作符优先级等问题。其实我们在写程序时函数用的更多一些,函数的优势更大一些
这里需要注意的是, x++ 和 y++ 都是后缀递增操作,它们会先返回变量的当前值,然后再将变量递增1。因此,在比较 (x++) > (y++) 时, x 和 y 的值分别为5和8。所以,比较结果为 false ,宏将执行 y++ 操作,此时y等于9,而 z 的值将为y++ 操作返回的值,即8
在执行完 MAX 宏之后, x 和 y 的值将分别递增为6和9。但这是一些编译器的结果,在另外一些编译器却会有另外一种结果:
即对于条件运算符? :,C 标准规定了条件部分((x++) > (y++))先求值,根据其结果选择求值冒号:前后的表达式之一(如果条件为真,求值(x++),否则求值(y++))。但是对于操作数内部的求值顺序(如x++和y++的求值顺序)是未定义的。
编译器可能会进行不同的优化,一些编译器可能先计算x++,再计算y++,用于比较(x++) > (y++)。假设先计算x++,此时x的值为 5(但之后x变为 6),再计算y++,y的值为 8(之后y变为 9),比较5 > 8为假,所以会计算y++来作为z的值,此时y先返回 8 作为z的值,然后y变为 9。这种情况下z的值为 8。
(5)宏与函数的对比:
二.#和##
1.#运算符:
2.##运算符:
三.#undef
四.条件编译
条件编译是C语言中一种用于根据特定条件包含或排除某段代码的技术
条件编译主要有以下几种形式:
1. 使用 #ifdef 和 #ifndef
#ifdef指令用于检查是否定义了某个宏。如果已定义,则编译其后的代码,否则,跳过该代码
#ifdef SOME_MACRO
// 当 SOME_MACRO 被定义时,这里的代码会被编译
#endif#ifndef指令与 #ifdef 相反,用于检查是否未定义某个宏
#ifndef SOME_MACRO
// 当 SOME_MACRO 未被定义时,这里的代码会被编译
#endif
2. 使用 #if,#elif,#else 和 #endif
#if`指令用于根据某个表达式的值(通常是宏定义)来决定是否编译某段代码。#elif 类似于 else if,#else 类似于 else,#endif` 用于结束条件编译块。
#if SOME_MACRO == 1
// 当 SOME_MACRO 等于 1 时,这里的代码会被编译
#elif SOME_MACRO == 2
// 当 SOME_MACRO 等于 2 时,这里的代码会被编译
#else
// 当 SOME_MACRO 不等于 1 且不等于 2 时,这里的代码会被编译
#endif
```
示例:假设我们有一个程序,它可以在调试模式和发布模式下运行。我们可以使用条件编译来实现这一功能
#include <stdio.h>// 定义一个宏来控制程序的运行模式
#define DEBUG_MODE 1int main() {int x = 42;#ifdef DEBUG_MODEprintf("调试模式:x = %d\n", x);
#elseprintf("发布模式:x = %d\n", x);
#endifreturn 0;
}
在这个示例中,我们使用 #ifdef 指令检查是否定义了 DEBUG_MODE 宏。如果定义了,则输出 "调试模式";否则,输出 "发布模式"。
条件编译在跨平台编程、库开发和调试过程中非常有用,通过使用条件编译,你可以轻松地为不同的编译环境、操作系统或硬件平台提供定制的代码
其他预处理指令: