宏和函数的区别(一个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 ...
随机推荐
- 添加linux系统调用的两种方式
原文:https://blog.csdn.net/sdulibh/article/details/51889279 向linux内核添加系统调用,一是通过编译内核添加,二是通过内核模块的方式添加: 一 ...
- Examples of GoF Design Patterns in Java's core libraries
设计模式分类 stackOverflow Structural(结构模式) Adapter:把一个接口或是类变成另外一种. java.util.Arrays#asList() javax.swing. ...
- gitlab访问用户安装的postgresql数据库
1.先将gitlab默认安装的postgresql的数据库中的数据,导入到用户安装的postgresql数据 用Navicat迁移数据.函数不用迁移. 2.配置gitlab对postgresql数据库 ...
- The iOS Simulator deployment target is set to 6.0
XCODE警告 Showing All Messages :-1: The iOS Simulator deployment target is set to 6.0, but the range o ...
- MySQL 5.7 的SSL加密方法
MySQL 5.7 的SSL加密方法 MySQL 5.7.6或以上版本 (1)创建证书开启SSL验证--安装opensslyum install -y opensslopenssl versionOp ...
- 报错解决——-bash: wget: command not found
本人用的是Mac本,在Mac中install的时候经常会用到wget,但是事先没有安装wget的话就会报上面的错误,解决方法就是安装wget. 安装wget 方法一:用传统的安装包方式安装 A - 从 ...
- Mac搭建PHP+rabbitMQ环境
RabbitMQ是一个在AMQP基础上实现的企业级消息系统.何谓消息系统,就是消息队列系统,消息队列是“”消费-生产者模型“”的一个典型的代表,一端往消息队列中不断写入消息,而另一端则可以读取或者订阅 ...
- [django]restfulapi请求规范
http://www.ruanyifeng.com/blog/2014/05/restful_api.html 方法及作用: GET(SELECT) :从服务器取出资源(一项或多项). POST(CR ...
- JS快速入门
字符串 模板字符串 需要特别注意的是,字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果: var s = 'Test'; s[0] = 'X'; alert(s); ...
- 大牛推荐的10本学习 Python 的好书
Python:蛇亚目蟒科,主要包括分布于非洲及亚洲的无毒蟒蛇. Python:Richard Clabaugh拍摄的恐怖电影,2000年发行. Python:澳大利亚汽车公司. Python:英国偶发 ...