宏和函数的区别(一个BUG的总结)
【1】BUG简单示例代码
主要代码如下:
#include <QCoreApplication>
#include <QDebug> #define ADD(a, b, c) ((a) + (b) + (c)) int func(int &n)
{
n += ;
return ;
} int addFunc(int a, int b, int c)
{
return (a + b + c);
} int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv); // begin main procedure
int a1 = ;
qDebug() << "macro result :: " << ADD(func(a1), a1 + , a1);
qDebug() << "macro expanse result :: " << (() + ( + ) + ());
int a2 = ;
qDebug() << "function result :: " << addFunc(func(a2), a2 + , a2);
// end main procedure return a.exec();
} // run out:
/*
macro result :: 231
macro expanse result :: 31
function result :: 31
*/
注意:宏、宏展开、函数调用的结果差异。
用宏计算时,宏中的参数由前至后赋值。
逐步分析:调用func(a1),调用结束后,宏的第一个参数值为1(即函数返回值),同时由于func为引用形参,a1此时值为110;
宏的第二个参数值为a1 + 10 = 120;宏的第三个参数值为a1 = 110。最后,宏计算值为231(1 + 120 + 110)
假如把宏展开,第一个参数值为1;第二个参数值为10 + 10 = 20;第三个参数值为10;所以结果为31(1 + 20 + 10)
用函数计算,调用函数时,参数压栈由后向前。
逐步分析:函数第三个参数值为a2 = 10;第二个参数值为a2 + 10 = 20;
第一个参数值为函数返回值1,尽管函数调用结束后a2值为110,但参数二、三已压栈赋值完成。
【2】使用宏和函数的区别
使用宏,宏中的参数由前至后。
使用函数,函数调用时,参数压栈顺序由后向前。
更多关于宏的资料,请参见《宏定义学习》
Good Good Study, Day Day Up.
顺序 选择 循环 总结
宏和函数的区别(一个BUG的总结)的更多相关文章
- C语言:带参数的宏与函数的区别
带参数的宏和函数很相似,但有本质上的区别:宏展开仅仅是字符串的替换,不会对表达式进行计算:宏在编译之前就被处理掉了,它没有机会参与编译,也不会占用内存.而函数是一段可以重复使用的代码,会被编译,会给它 ...
- 与number_format函数有关的一个bug?
最近在做一个模仿excel功能的在线项目.其中有一个功能,数据列表中的数据,到了最后一列都要进行总计.这本来没什么难度.直接从数据库取出数据后,进行foreach相加就行 了.这是如此的简单,以至于用 ...
- C/C++之宏、内联函数和普通函数的区别
内联函数的执行过程与带参数宏定义很相似,但参数的处理不同.带参数的宏定义并不对参数进行运算,而是直接替换:内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算 ...
- [ 随手记 1 ] C/C++宏,普通函数,内联函数
函数定义 C 语言中的函数定义的一般形式如下: return_type function_name( parameter list ) { body of the function } 在 C 语言中 ...
- js new一个函数和直接调用函数的区别
用new和调用一个函数的区别:如果函数返回值是一个值类型(Number.String.Boolen)时,new函数将会返回这个函数的实例对象,而如果这个函数的返回值是一个引用类型(Object.Arr ...
- C++内联函数、宏定义和普通函数的区别
C++内联函数.宏定义和普通函数的区别? 宏定义:在预处理阶段进行简单的文本替换,不会进行参数类型检查: 内联函数:在编译器的时候进行代码插入,编译器会在每次调用内联函数的地方直接将内联函数的内容展开 ...
- C语言带参宏定义和函数的区别
带参数的宏和函数很相似,但有本质上的区别:宏展开仅仅是字符串的替换,不会对表达式进行计算:宏在编译之前就被处理掉了,它没有机会参与编译,也不会占用内存.而函数是一段可以重复使用的代码,会被编译,会给它 ...
- NDK中使用pthread多线程中自己写的一个BUG
在使用pthread进行NDK中的多线程开发时,自己写了一个BUG, void *darkGrayThread(void *args) { ThreadParam *param = (ThreadPa ...
- MySQL关于exists的一个bug
今天碰到一个很奇怪的问题,关于exists的, 第一个语句如下: SELECT ) FROM APPLY t WHERE EXISTS ( SELECT r.APPLY_ID FROM RECORD ...
随机推荐
- Mysql 数据库几种引擎的区别比较
· MyISAM:默认的MySQL插件式存储引擎,它是在Web.数据仓储和其他应用环境下最常使用的存储引擎之一.注意,通过更改STORAGE_ENGINE配置变量,能够方便地更改MySQL服务器的默认 ...
- mysql批量插入数据
建表 create table `dept`( `id` ) unsigned NOT NULL AUTO_INCREMENT, `deptno` mediumint() unsigned ', `d ...
- mysql命令行各个参数解释
mysql命令行各个参数解释 http://blog.51yip.com/mysql/1056.html Usage: mysql [OPTIONS] [database] //命令方式 -?, ...
- Java基础知识(重载和覆盖)
重载(overload): 在一个类中,如果出现了两个或者两个以上的同名函数,只要它们的参数的个数,或者参数的类型不同,即可称之为该函数重载了. 即当函数同名时,只看参数列表.和返回值类型没关系. 重 ...
- FastReport快速入门
界面及连接关系 frxDBDataset1连接datasource 双击frxReport1控件进入设计界面,选择报表->数据,弹出窗口选择要显示数据的frxdbdataset,frxdbdat ...
- GUI库之认识Tkinter(一)
一.介绍 Tkinter是Python默认的GUI库,我们经常使用的IDLE就是用Tkinter设计出来的,因此我们在使用的时候直接导入Tkinter模块就好了. 1.特点:可移植性.灵活性高 2.构 ...
- 这可能是由于 CredSSP 加密 Oracle 修正。
1.Win+R 输入regedit打开注册表 找到对应的以下目录 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Polici ...
- Wi-Fi 协议和数率?
IEEE 802.11Wi-Fi 协议摘要 协议 频率 信号 最大数据速率 传统 802.11 2.4GHz FHSS 或 DSSS 2Mbps 802.11A 5GHz OFDM 54Mbps 80 ...
- nginx 部署web页面问题
nginx 部署web页面的时候,路径都是对的,但是css文件就是不起作用,控制台提示如下,原来是格式的问题,截图如下: css 被转成了application/octet-stream,这个是ngi ...
- element
<el-table-column label="地址" prop="address"> <template slot-scope=" ...