如何使用宏来定义一个自定义函数呢?
首先我们来看下面这段代码

#define SQUARE(x) x*x
int main()
{
int a = 5;
printf("SQUARE(a): %d\n",SQUARE(a)); //这个值为25
printf("SQUARE(a+1): %d\n", SQUARE(a + 1)); //第一反应是打印36,其实打印的是11
}

运行结果:

为什么会出现这样的结果呢?原因是编译器在处理SQUARE(a+1)的时候,处理成了 a+1a+1 ,所以a = 5时,最后结果为 11,当我们的宏定义为 #define SQUARE(x) xx 时,结果就是36,那这种宏的定义方法是正确的吗?
再看看下面这段代码:

#define MAX(a,b) (a>b?a:b)
int main()
{
int a = 5;
int b = 3;
printf("MAX(a, b): %d\n", MAX(a, b)); //很明显,打印的是5.
printf("MAX(a&1, b&1): %d\n", MAX(a&1, b&)); //这里打印的是5吗?
}

运行结果如下:

那这又是怎么回事呢?原因是编译器将 MAX(a&1, b&1) 处理为 a&1>b&1?a&1:b&1 ,这里就要考虑运算符的优先级问题了。这篇博客介绍了C语言运算符优先级 。
所以我们可以看到>的优先级高于&,所以运算过程如下图:

总结:宏函数的正确写法是 每一个元素加括号,并且在最外层也加括号,如#define MAX(a,b) ((a)>(b)?(a):(b?).
仅为个人理解,如有错误请指出!
---------------------
作者:故渊~
来源:CSDN
原文:https://blog.csdn.net/lvxin15353715790/article/details/87891991
版权声明:本文为博主原创文章,转载请附上博文链接!

参考链接:

详解宏定义(#define)【转】 - biqioso的博客 - CSDN博客  https://blog.csdn.net/biqioso/article/details/80420152

#define定义宏函数 的正确使用的更多相关文章

  1. c c++ #define 定义假函数

    #define   Add(a,b)   ((a)+(b)) #define Max(a,b) ((a)>(b)?(a):(b)) 这就定义了一个假的函数 说白了就是字符串替换 这样在写代码时能 ...

  2. 结构体中使用#define定义宏

    struct  hostent {   char    *h_name;        /* official name of host */   char    **h_aliases;    /* ...

  3. php基础:define()定义常数函数

    define(); 常量类似变量,不同之处在于: 在设定以后,常量的值无法更改 常量名不需要开头的美元符号 ($) 作用域不影响对常量的访问 常量值只能是字符串或数字 <?php define( ...

  4. [c++] 用宏定义一个函数

    要点:变量都用括号括起来,防止出错,结尾不需要;.在实际编程中,不推荐把复杂的函数使用宏,不容易调试.多行用\ 要写好C语言,漂亮的宏定义是非常重要的.宏定义可以帮助我们防止出错,提高代码的可移植性和 ...

  5. C++中的间接宏函数

    宏函数对于每个C++程序员都决不陌生,就算是初出茅庐的C++程序员也知道如何定义.使用宏函数.   但是当初学者看到类似于以下这种宏函数嵌套的时候,可能还是会比较嘀咕, #define CONVERT ...

  6. IOS学习之路-- 指针&宏函数

    如果*p被()包住,说明指针变量p将来指向的是函数 //声明一个指针变量 //int (*p)(int, int) = sum; int (*p)(int, int); p = sum; // 如果* ...

  7. 使用#define定义字面值和伪函数

    #define是C语言提供的宏命令,其主要目的是:在编程时,为程序员提供一定方便,并能在一定程度上提高程序的执行效率.#define将一个标示符定义为一个字符串,该标示符被称为宏,被定义的字符串称为字 ...

  8. readb(), readw(), readl(),writeb(), writew(), writel() 宏函数【转】

    转自:http://www.netfoucs.com/article/hustyangju/70429.html readb(), readw(), readl()函数功能:从内存映射的 I/O 空间 ...

  9. C/C++预定义宏

    编译器识别预定义的 ANSI/ISO C99 C 预处理宏,Microsoft C++ 实现将提供更多宏.这些预处理器宏不带参数,并且不能重新定义. ANSI 兼容的预定义宏 __FILE__,__L ...

随机推荐

  1. Guide 哥:有哪些程序员受用一生的好习惯?

    本文来自 Guide 哥开源的 Github 仓库 programmer-advancement:https://github.com/Snailclimb/programmer-advancemen ...

  2. js 超浓缩 双向绑定

    绑定确实是个有趣的话题. 现在我的绑定器有了不少的功能 1. 附着在Object对象上,一切以对象为中心 2. 与页面元素进行双向绑定 3. 与任意对象绑定,主要是应用在绑定到页面元素的一些属性上,比 ...

  3. c# winform找窗体

    Application.OpenForms["frm"],一句话就找到窗体

  4. java实现判定新旧版本号

    废话不多说,直接上代码 /** * 判断是否为最新版本方法 将版本号根据.切分为int数组 比较 * * @param localVersion 本地版本号 * @param onlineVersio ...

  5. el表达式获取url中携带的参数

    使用JSTL时,URL会被隐含的对象param包裹起来,使用param.变量名,直接获取值 <body>hello:${param.name}</body> 在使用jquery ...

  6. WinPE基础知识之头部

    1.DOS头 // DOS MZ头,大小为64个字节 typedef struct _IMAGE_DOS_HEADER { WORD e_magic; // EXE标志,“MZ”(有用,解析时作为是否 ...

  7. 7.Spring整合Hibernate_1

    Spring 整合 Hibernate 1.Spring指定 database,给下面创建的 SessionFactory用 <!-- !!!!!可以使用 @Resource 将 这个bean对 ...

  8. sqlserver 2008修改数据库表的时候错误提示“阻止保存要求重新创建表的更改”

    当用户在在SQL Server 2008企业管理器中更改表结构时,必须要先删除原来的表,然后重新创建新表,才能完成表的更改,如果强行更改会出现以下提示:不允许保存更改.您所做的更改要求删除并重新创建以 ...

  9. 数学模块 math 函数的调用

    数学模块 math 模块名: math 注: linux下为内建模块 Mac OS下为标准库模块 数学模块用法: import math # 或 from math import * 数据 描述 ma ...

  10. 《浏览器工作原理与实践》<04>从输入URL到页面展示,这中间发生了什么?

    “在浏览器里,从输入 URL 到页面展示,这中间发生了什么? ”这是一道经典的面试题,能比较全面地考察应聘者知识的掌握程度,其中涉及到了网络.操作系统.Web 等一系列的知识. 在面试应聘者时也必问这 ...