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

#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. RSA加密,以及证书加密

    简单的加密:https://blog.csdn.net/qq_32523587/article/details/79092364 生成证书:https://blog.csdn.net/u0121916 ...

  2. nginx做为web容器部署静态资源以及做负载均衡反向代理实现

    需求:  此时前台开发完成打包生成静态资源文件,要做到以下方面: 使用nginx部署静态资源,同时nginx要实现端口转发,隐藏真实后台地址,同时后台需要做一个负载均衡. localhost:7001 ...

  3. TCP协议探究(三):RTT、滑动窗口和阻塞处理

    1 RTT算法 1.1 概述 上一节说了重传机制需要设置一个重传超时值(RTO,Retransmission TimeOut),RTO设长了,重发太慢:设短了,可能导致包没有丢,就重发了,可能导致雪崩 ...

  4. sqlserver查询数据的所有表名和行数及空间占用量

    //查询所有表名 select name from sysobjects where xtype='u' --modify_date指表结构最后更新日期,并非数据最后更新日期SELECT     na ...

  5. Python爬取爱奇艺资源

    像iqiyi这种视频网站,现在下载视频都需要下载相应的客户端.那么如何不用下载客户端,直接下载非vip视频? 选择你想要爬取的内容 该安装的程序以及运行环境都配置好 下面这段代码就是我在爱奇艺里搜素“ ...

  6. 异步处理的框架Sanic的使用方法和小技巧

    Sanic是异步处理的框架,运用Sanic可以开发快速异步响应的web程序.想必大家看到这个都会比较期待和兴奋. 那么如何使用Sanic来实现快速响应呢?我们先来看一看Sanic的基本介绍. Sani ...

  7. Redis5.0.3单机版安装

    一.创建redis源码包存放目录 cd /usr/local/ mkdir redis 二.进入创建的目录,下载最新版Redis yum -y install wget wget http://dow ...

  8. (a ==1 && a== 2 && a==3) 有可能是 true 吗?

    今天看到这个题目,感到很有意思,查找了些资料,各位牛人果然有高招解决: 方法一: var a = { i: 1, toString: function () { return a.i++; } } i ...

  9. stat /var/lib/docker/tmp/docker-builder234542842/usr/local/resource/noah_init.sql

    参考:https://blog.csdn.net/andrew_wf/article/details/85202511 将noah_init.sql放到与Dockerfile同一目录

  10. 用tensorflow实现SVM

    环境配置 win10 Python 3.6 tensorflow1.15 scipy matplotlib (运行时可能会遇到module tkinter的问题) sklearn 一个基于Python ...