【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的总结)的更多相关文章

  1. C语言:带参数的宏与函数的区别

    带参数的宏和函数很相似,但有本质上的区别:宏展开仅仅是字符串的替换,不会对表达式进行计算:宏在编译之前就被处理掉了,它没有机会参与编译,也不会占用内存.而函数是一段可以重复使用的代码,会被编译,会给它 ...

  2. 与number_format函数有关的一个bug?

    最近在做一个模仿excel功能的在线项目.其中有一个功能,数据列表中的数据,到了最后一列都要进行总计.这本来没什么难度.直接从数据库取出数据后,进行foreach相加就行 了.这是如此的简单,以至于用 ...

  3. C/C++之宏、内联函数和普通函数的区别

    内联函数的执行过程与带参数宏定义很相似,但参数的处理不同.带参数的宏定义并不对参数进行运算,而是直接替换:内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算 ...

  4. [ 随手记 1 ] C/C++宏,普通函数,内联函数

    函数定义 C 语言中的函数定义的一般形式如下: return_type function_name( parameter list ) { body of the function } 在 C 语言中 ...

  5. js new一个函数和直接调用函数的区别

    用new和调用一个函数的区别:如果函数返回值是一个值类型(Number.String.Boolen)时,new函数将会返回这个函数的实例对象,而如果这个函数的返回值是一个引用类型(Object.Arr ...

  6. C++内联函数、宏定义和普通函数的区别

    C++内联函数.宏定义和普通函数的区别? 宏定义:在预处理阶段进行简单的文本替换,不会进行参数类型检查: 内联函数:在编译器的时候进行代码插入,编译器会在每次调用内联函数的地方直接将内联函数的内容展开 ...

  7. C语言带参宏定义和函数的区别

    带参数的宏和函数很相似,但有本质上的区别:宏展开仅仅是字符串的替换,不会对表达式进行计算:宏在编译之前就被处理掉了,它没有机会参与编译,也不会占用内存.而函数是一段可以重复使用的代码,会被编译,会给它 ...

  8. NDK中使用pthread多线程中自己写的一个BUG

    在使用pthread进行NDK中的多线程开发时,自己写了一个BUG, void *darkGrayThread(void *args) { ThreadParam *param = (ThreadPa ...

  9. MySQL关于exists的一个bug

    今天碰到一个很奇怪的问题,关于exists的, 第一个语句如下: SELECT ) FROM APPLY t WHERE EXISTS ( SELECT r.APPLY_ID FROM RECORD ...

随机推荐

  1. liteide 去除go程序cmd窗口

    http://blog.csdn.net/aqtata/article/details/53389261

  2. 下载pywinauto

    1.下载pywinauto 链接:http://pywinauto.github.io/ 2.将安装包放到D:python36\script,进入pywinauto目录,按shift+右键,进入命令窗 ...

  3. pip升级时报错--- No module named 'pip._internal'

           一.问题:        之前python3.6是安装的pip版本为:pip=9.0.1,我按照提示升级报错,一直装不上pip18.0,于是直接在site-package目录下删掉了pi ...

  4. 百度接口test

    https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=Mk2Orf5pqEOXvYR ...

  5. 八种排序算法--java实现(转)

    (转:http://blog.csdn.net/without0815/article/details/7697916) 8种排序之间的关系: 1, 直接插入排序 (1)基本思想:在要排序的一组数中, ...

  6. PHP 注册错误和异常处理机制

    注册错误和异常处理机制有三个PHP函数需要学习 1. register_shutdown_function('Bootstrap\Library\Frame::fatalError'); 2. set ...

  7. 万恶之源 - Python模块二

    shelve 我们之前学了json和pickle模块 这些都是序列化的模块,咱们进行在讲一个序列化的东西 叫做shelve 你们肯定有个疑问,这个东西和那个类似为什么要讲.是因为这个模块比较简单的,并 ...

  8. Jmeter测试报告

    服务器: 2个CPU,每个CPU 1个核,4G内存  20G硬盘 客户端(Jmeter):2个CPU,每个2个核,4+8内存   500G硬盘 ---------------------------- ...

  9. [Java in NetBeans] Lesson 10. For Loops

    这个课程的参考视频和图片来自youtube. 主要学到的知识点有:(the same use in C/C++) 1. x++, x += 1; similar x--, x -= 1; x *= 2 ...

  10. js模拟链表---双向链表

    双向链表: 每个元素,有一个 next(指向下一个元素)和一个prev(指向前一个元素) function dbLinkedList(){ var length=0; var head = null; ...