| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> C语言预处理指令详解(一) -> 正文阅读 |
|
[C++知识库]C语言预处理指令详解(一) |
目录 一.常见预处理符号
这些预处理符号均为C语言内置,可直接使用,如下图,打印显示了相关信息,且可看出在vs2019编译器环境,__STDC__未定义 二.#define 定义标识语法:?#define name stuff 例如:
行1将MAX标识符定义为1000,MAX则为标识符常量,行2将register替换为reg 其原理为标识符的替换,在预处理完成后,程序会将目标代码中相关标识符直接进行替换,如MAX将被直接替换为100,替换完成后效果如下:
三.#define 定义宏语法:#define name( parament-list ) stuff #define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro),其中的 parament-list 是一个由逗号隔开的符号表。 注意: 参数列表的左括号必须与name紧邻。 如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分。
以上代码便定义了一个宏,用于实现X与Y的相加。此时若在代码中使用此宏,如:
则预处理后实际效果为:
?可能存在的问题 1.宏定义中的参数 宏定义的机制十分类似与函数,而其中符号表部分也与函数参数极其相似,这也容易使人产生错误,要注意,#define的机制始终是替换的效果,而非参数传值!如下,不妨想想结果是什么:
以上代码极容易被误解成5*2=10,但实际上,按照宏定义,实际结果应为4+1*2=6。因此在定义时,我们最好给"参数"部分加上括号以改变优先级。
2.宏定义的值 除了参数,宏定义的值和函数"返回值"的相似性也会造成误解
对于以上代码,结果又是多少呢? 由于函数返回值的错觉,结果容易被误解为10*5=50,然而实际上,运算应该为 10*(2)+(3)=23,因此在对于整个宏定义表达式,最好也加上括号
3.宏参数的副作用 当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么你在使用这个宏的时候就也可能出现危险,导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。 例如:?
由于"替换"的特性,其预处理实际执行后为: ( (x++) > (y++) ? (x++) : (y++) ),因此执行完毕后,实际x=6,y=10,z=9。由此我们可以看出,若参数带有副作用,可能产生意料之外的效果 四.#define 替换规则在程序中扩展#define定义符号和宏时,需要涉及几个步骤。 1. 在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换。 2. 替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换。 3. 最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程。 注意: 1. 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。 2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。 五.宏和函数对比?宏通常被应用于执行简单的运算。 比如在两个数中找出较大的一个。 那为什么不用函数来完成这个任务? 原因有二:
宏的缺点:
由此代码可以看出,宏的函数可以出现类型等,因此可以实现函数难以完成的工作,当然函数也能实现宏定义无法实现的递归,两者各有优势。 六.宏用法的拓展-#和##首先来看以下代码:
打印结果仍为hello world,我们发现字符串是有自动连接的特点的。了解这一点之后,我们可以学习宏参数中的#和## 1.#的作用-把一个宏参数变成对应的字符串? 如何把参数名插入到字符串中?
由宏定义的#修饰和字符串的自动拼接,其实际效果为printf("the value of " "i" " is "FORMAT "\n", VALUE),打印为the value of i is 10,便实现了参数名插入字符串。 2.##的作用-##可以把位于它两边的符号合成一个符号。 它允许宏定义从分离的文本片段创建标识符。
其实际效果为把参数num+=10?,即n##um合成为了标识符num。当然,这样的连接必须产生一个合法的标识符。否则其结果就是未定义的。 七.命名约定一般来讲函数的宏的使用语法很相似。所以语言本身没法帮我们区分二者。 我们平时的一个习惯是: 把宏名全部大写,函数名不要全部大写 |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 4:56:09- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |