预处理指令

本文详细介绍了C/C++的预处理指令,包括宏定义、条件编译和文件包含。宏定义允许在编译前替换指定标识符,条件编译用于根据条件选择性编译代码,文件包含则能复用代码。预处理指令在程序开发中起到关键作用,如简化代码、提高效率和代码复用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

预处理指令

在文件翻译成0和1之前做的操作我们称之为预处理指令
一般情况预处理指令都是以#号开头

预处理指令分为宏定义、条件编译、文件包含

宏定义
宏定义的作用

会在程序翻译成0和1之前,将所有宏名替换为宏的值

宏名定义规范
  • 定义宏名使用 #define 宏名 进行定义,宏名尾部不需要用分号结尾
  • 定义宏名的2种方式:
    • 1.宏名使用大写字母,多个单词用下划线隔开。例如:#define COUNT
    • 2.宏名使用k开头,多个单词直接使用驼峰命名。例如:#define kClassCount

注意: 宏定义不要以分号结尾

宏定义的作用域
  • 从定义的那一行开始,一直到文件末尾
  • 虽然默认情况下宏定义的作用域是从定义的那一行开始,一直到文件末尾,但是我们也可以通过对应的关键字undef提前结束宏定义的作用域
宏定义的使用场景
  • 我们的app需要频繁的于api进行交互获取数据进行展示,不同页面调用api的路由不同,但是域名是相同的,此时可以将域名定义为宏
#include <stdio.h>

// 定义宏变量API_DOMAIN
#define API_DOMAIN "http://api.api.com"

int main(int argc, const char * argv[]) {
    char loginApi[] = API_DOMAIN"/login";		// 使用宏定义
    printf("loginApi --> %s\n", loginApi);      // loginApi --> http://api.api.com/login

    return 0;
}

  • 获取手机屏幕的宽度
  • 获取手机系统版本号

个人理解: 宏定义其实就是类似于其它语言中的常量定义

不带参数和带参数的宏定义
  • 不带参数的宏定义
#include <stdio.h>

// 定义宏变量API_DOMAIN
#define API_DOMAIN "http://api.api.com"

int main(int argc, const char * argv[]) {
    char loginApi[] = API_DOMAIN"/login";		// 使用宏定义
    printf("loginApi --> %s\n", loginApi);      // loginApi --> http://api.api.com/login

    return 0;
}

  • 带参数的宏定义
#include <stdio.h>

// 宏定义不会做任何运算,只是一个简单的替换
#define API_DOMAIN2(route) "http://api.api.com"route

int main(int argc, const char * argv[]) {
    char loginApi[] = API_DOMAIN2("/login");
    printf("loginApi --> %s\n", loginApi);      // loginApi --> http://api.api.com/login
    
    return 0;
}

条件编译

条件编译使用关键字#if、#ifdef、#ifndef

  • #if 用于判断表达式
#define COUNT 10

#if COUNT == 10
	printf("COUNT == 10");
#elif COUNT == 20
	printf("COUNT == 20");
#else
	printf("COUNT 值异常");
#endif
  • #ifdef 用于判断宏变量是否定义
#define COUNT 10

// 判断宏变量COUNT是否定义
#ifdef COUNT
	printf("COUNT被定义");
#else
	printf("COUNT未定义");
#endif
  • #ifndef 用于判断宏变量是否未定义
// 判断宏变量COUNT是否未定义
#ifndef COUNT
	printf("COUNT未被定义");
#else
	printf("COUNT定义");
#endif

条件编译会对给定的条件进行判断,如果条件满足就编译条件后面的内容,与if条件判断类似
条件编译不能用来判断变量,因为不在同一声明周期
一般情况下,条件编译是和宏定义结合在一起使用的

#include <stdio.h>

#define DEBUG 0     // 0表示调试阶段,1表示发布阶段

#if DEBUG == 0
#define NJLog(format, ...) printf(format, ## __VA_ARGS__)
#elif DEBUG == 1
#define NJLog(format, ...)
#endif

int main(int argc, const char * argv[]) {
    
    int i = 10;
    
    // 当DEBUG等于0的时候,会将 NJLog("i --> %i\n", i) 替换为 printf("i --> %i\n", i)
    NJLog("i --> %i\n", i);     // i --> 10
    
    return 0;
}

条件编译和if的区别
共同点:

  • 都可以对给定的条件进行判断
  • 添加满足或者不满足都可以执行特定的代码
  • 可以执行多个表达式

不同点:

  • 生命周期不同,if 是运行时,#if 是在编译之前
  • #if 需要一个明确的结束符号 #endif。如果省略掉#endif,那么系统就不知道条件编译的范围,那么会满足条件之后的第二个条件之后的所有内容都清除掉
  • if 会将所有的代码都编译到二进制中,#if 只会将满足条件的代码块编译到二进制中

#if 的优点

  • 缩小应用程序的大小
文件包含

文件包含使用 #include 指令
详情参考:https://blog.youkuaiyun.com/crazy_zhangcong/article/details/87939292

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值