小心!#define max(a,b) a>b?a:b
今天做oj的时候,定义了两个宏:
//wrong code
#define max_2(a,b) a>b?a:b
#define max_3(a,b,c) (a>b?a:b)>c?(a>b?a:b):c
然后程序结果总是WA,仔仔细细检查程序的逻辑一遍又一遍,都快抓狂了,最后终于发现是我定义的两个宏有问题。改为如下就AC了:
#define max_2(a,b) (a>b?a:b)
#define max_3(a,b,c) ((a>b?a:b)>c?(a>b?a:b):c)
对的,就是差两个括号,没有括号,因为优先级不一样,造成运算顺序并不是我们预期的那样,运算结果错误。
下边是分析过程:
先上两段有问题的代码:
#include <iostream>
#define max_2(x,y) x>y?x:y
using namespace std; int main()
{
int a=max_2(,)+;
int b=max_2(,)+;
int c=max_2(,);
int d=max_2(,);
int e=(max_2(,)+);
cout<<a<<" "<<b<<endl;
cout<<c<<" "<<d<<endl;
cout<<e<<endl; return ;
}
运行结果:
从程序中变量c、d可以发现,max_2(x,y)里不论x、y的顺序如何,max_2(x,y)能够返回正确的结果;
从程序中变量a、b可以发现,运算顺序跟max_2(x,y)里x、y的顺序有关,当x>y时,程序先将max_2(2,1)的结果赋给b,而不是加3之后再赋给b;
从程序中变量e可以发现,即使加了括号,也不能改变这种运算顺序。
另一段问题代码,如下图,编译都不能通过:
所以,不要忘了关键的括号,不然害人不浅。
小心!#define max(a,b) a>b?a:b的更多相关文章
- C/C++预处理指令#define,#ifdef,#ifndef,#endif…
2016年12月29日更新: 今天查看以前文件的时候, 突然发现了#error 这个预处理指令.然后回想一下工作, 发现这个指令使用场景还是很多的.比如: 一个项目的模块儿之多,源文件之大,代码之多, ...
- C++#define的用法(含特殊)
1 无参宏定义无参宏的宏名后不带参数.其定义的一般形式为: #define 标识符 字符串其中的“#”表示这是一条预处理命令.凡是以“#”开头的均为预处理命令.“define”为宏定义命令.“标 ...
- C/C++预处理指令#define,#ifdef,#ifndef,#endif… (转)
本文转自博文C/C++预处理指令#define,#ifdef,#ifndef,#endif….这篇博文写得特别好,特转载. 本文主要记录了C/C++预处理指令,常见的预处理指令如下: #空指令,无任何 ...
- #define const typedef
#define用法 1. 定义简单的常数:定义常量,便于修改 #define N 1000 2. 定义简单的函数:注意多使用括号 define可以像函数那样接受一些参数,如下: #define max ...
- 预处理、const、static与sizeof-用#define实现宏并求最大值和最小值
1:实现代码: #define MAX(x,y) (((x)>(y)) ? (x):(y)) #define MIN(x,y) (((x)>(y)) ? (x):(y)) 需要注意的几点: ...
- C/C++预处理指令#include,#define,#undef,#if,#ifdef,#ifndef,#elif,#endif,#error......
本文主要记录了C/C++预处理指令,常见的预处理指令如下: #空指令,无任何效果 #include包含一个源代码文件 #define定义宏 #undef取消已定义的宏 #if如果给定条件为真,则编译下 ...
- effetive C++ 02 尽量以const,enum,inline替换#define
#define ASPECT_RATIO=1.1const double AspectRatio=1.1 1. 使用宏会导致预处理器把程序代码中的ASPECT_RATIO无条件替换为1.1,编译器从未 ...
- IOS 基础-define、const、extern、全局变量
这里介绍一下define.const.extern的用法.优劣以及要注意的地方. 1.define 宏define是定义一个变量,没有类型信息.define定义的常量在内存中有若干个拷贝. defin ...
- HDU 1024 max sum plus
A - Max Sum Plus Plus Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I6 ...
随机推荐
- C#定时器和事件
C#定时器和事件 System.Timers.Timer myTimer; private void Form1_Load(object sender, EventArgs e) { myTimer ...
- SATA SAS SSD 硬盘介绍和评测
SATA SATA的全称是Serial Advanced Technology Attachment,是由Intel.IBM.Dell.APT.Maxtor和Seagate公司共同提出的硬盘接口规范. ...
- Unity学习笔记(4):依赖注入
Unity具体实现依赖注入包含构造函数注入.属性注入.方法注入,所谓注入相当赋值,下面一个一个来介绍 1:构造函数注入 1.1当类有多个构造函数时,可以通过InjectionConstructor特性 ...
- 版本控制器 (Svn,Git)
Svn: 集中式版本控制器,首先开发者在开始新一天的工作之前必须从服务器获取代码,然后进入自己的分支开发,开发完成后把自己的分支合并到主分支上进行提交,解决冲突.所有的版本信息都放在服务器上.如果脱离 ...
- 简单的下拉刷新以及优化--SwipeRefreshLayout
代码工程简要说明:以一个SwipeRefreshLayout包裹ListView,SwipeRefreshLayout接管ListView的下拉事件,若ListView被用户触发下拉动作后,Swipe ...
- 单例模式C#
首先来明确一个问题,那就是在某些情况下,有些对象,我们只需要一个就可以了, 比如,一台计算机上可以连好几个打印机,但是这个计算机上的打印程序只能有一个, 这里就可以通过单例模式来避免两个打印作业同时输 ...
- 常见前端面试题之HTML/CSS部分
转自http://www.cnblogs.com/jscode/archive/2012/07/10/2583856.html Doctype是什么?如何触发严格模式与混杂模式模式?区分它们有何意义? ...
- Java 8 VM GC Tuning Guide Charter3-4
第三章 Generations One strength of the Java SE platform is that it shields the developer from the compl ...
- 活动 Activity 四种加载模式
singleTop要求如果创建intent的时候栈顶已经有要创建的Activity的实例,则将intent发送给该实例,而不发送给新的实例.(注意是栈顶,不在栈顶照样创建新实例!) singleTas ...
- hihocoder #1301 : 筑地市场 数位dp+二分
题目链接: http://hihocoder.com/problemset/problem/1301?sid=804672 题解: 二分答案,每次判断用数位dp做. #include<iostr ...