【学习打卡】第3天 宏函数、条件编译
2022/8/7 3:22:49
本文主要是介绍【学习打卡】第3天 宏函数、条件编译,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
课程名称:C语言系统化精讲 重塑编程思想 打造坚实的开发基础
课程章节:第五章 预处理和宏
授课老师:bennyhuo
课程内容
C宏函数
C语言中 除了简单的利用 宏代替常量以外,我们也可以利用宏编写简单的宏函数。
之所以能称之为函数,是因为其可以带入参数。
简单的例子:
#define MAX(a,b) a>b ?a :b int max = MAX(1, 3)
但注意,这样的定义,在嵌套时,可能会出现错误,来源于替换后各种表达式的优先级不同。所以,在实际情况中,我们一般会添加一对括号,保证参数在进行运算时始终保持表达式的独立计算。
实际情况:
#define MAX(a,b) (a) > (b) ? (a) : (b)
另一个特例,如果在表达式中有自增运算,在替代后,会不经意间多计算一次:
max = MAX(max++, 5) -> max = (max++) > 5 ? (max++) :5 // 多执行了一次
总之,在写完宏后,使用宏函数的过程要保证使用 没有副作用 的表达式。
ps:副作用是语言中的一个概念,即表达式和函数不改变变量或者状态,只返回某个值。
多行宏使用 \
连接:
#define IS_HEX_CHARACTER(ch) \ ((ch) >= '0' && (ch) <= '9' ) || \ ((ch) >= 'A' && (ch) <= 'F' )|| \ ((ch) >= 'a' && (ch) <= 'f )
宏展开,\
并不会替换,换行符只是给编译器看的。而宏函数又因为自身没有类型的要求,所以其 可在C 中被用来方便的进行多类型的通用函数。
条件编译
在头文件中,我们常见可以见到如下宏定义:
#ifdef XXXXX_H #define XXXXX_H //statement #endif
那么既然引入头文件就可以将一些函数引入,为什么要加入这些判断呢?
答案就是 :防止引入同一个头文件多次 ,因为引入同一段函数多次,在编译上一般会报错。
在多个头文件文件互相引入的时候,这可以有效避免多次引入同一段函数。
而条件编译的语句含义也非常明显:
1. #ifdef : 如果定义了 2. #ifndef : 如果没定义 3. #if 如果... 最后,他们都要和 #endif 搭配 而
有一个通用的小技巧,便是使用 defined ()
这个函数可以判断宏是否定义,通常搭配 #if
实现和ifdef
同样的作用。最终达到在不同宏,实现不同功能的作用,如:
void dump(char *message){ #ifdef DEBUG puts(message); #endif }
当然你可以定义 #define DEBUG 做到调试开关的作用,更方便的做法是:
在编译时,只要了加上了宏 gcc -D DEBUG 即可
CMAKE中,如下加入定义:
target_compile_definition(${name} PUBLIC DEBUG)
有一个有意思的东西,可以判断在 C or C++ 的环境:
#ifdef __cplusplus extern "C"{ #endif //.... #ifdef __cplusplus }; #endif
当然,宏编译对于跨平台编译也非常好用:
课程收获
- 理解了为什么要有条件编译
- 条件编译对 DEBUG 类的编译的作用
- 稍微熟悉了 CMAKE 中 添加编译选项的方法
这篇关于【学习打卡】第3天 宏函数、条件编译的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)
- 2024-05-30【Java】百万数据excel导出功能如何实现
- 2024-05-30我们小公司,哪像华为一样,用得上IPD(集成产品开发)?