c宏的MAX函数
今天从香山上面回来累的跟傻逼一样,回来问了一下胡总的阿里面试的问题。然后其中有一个是宏写max函数。胡总说不好写,然后我就去洗澡了。
洗澡的时候感觉不对啊,回来写了一个:
#define MAX(a,b) a>b?a:b;
测了一下可以。然后胡总说搞个++就不行了。然后有了如下代码:
int x = ;
int y = ;
scanf("%d%c",&x,&y);
printf("%d\n",MAX(x,y++));
printf("%d",y);
这里打印出来的是:
7
8
显然y++被执行了两次,宏跟函数的传递方式不一样,宏是以替换的形式,而函数是先求值再传参数。因此这里其实是执行了 x > (y++)?x:y++,显然y++执行了两次
之后网上搜了一下,又有了下面的版本:
#define max(x,y) ({typeof(x) _x = (x);typeof(y) _y = (y);(void)(&_x == &_y);_x > _y ? _x : _y; })
这里其实是声明了两个变量_x和_y然后进行比较。
其中关键的一句是(void)(&_x == &_y)。
这句话判断了_x和_y的类型是否相等。因为据说c语言不能直接判断typeof()是否相等。
然后这里是判断&x和&y是否相等,就是判断x和y的指针是否相等。在判断两个变量是否相等的时候,编译器会先判断两个变量的类型是否相等。如果x和y的类型不等,那么他们对应的指针类型自然不会相等(编译的时候会产生waring)。
前面的(void)的意义在于将判断两个指针是否相等的结果抛弃。不然据说会提示这段代码没用。
更加安全的办法,应该在typeof前面加一个const,这样会避免对_x和_y的误操作。
c宏的MAX函数的更多相关文章
- JS Math.max() 函数
Math.max(a,b,...,x,y) -- 返回数个数字中较大的值 max是maximum的缩写,中文"最大量"的意思 max函数语法Math.max(a,b,...,x,y ...
- [数据库]关于MAX()函数的一个坑
之前写了这么一条sql语句,目的是取出表中itemid最大的那一条数据. SELECT date, MAX(itemid) AS itemid, group FROM mytable GROUP BY ...
- Matlab:max函数
Matlab中max函数在矩阵中求函数大小的实例如下: C = max(A)返回一个数组各不同维中的最大元素.如果A是一个向量,max(A)返回A中的最大元素.如果A是一个矩阵,max(A)将A的每一 ...
- oracle max()函数和min()函数
当需要了解一列中的最大值时,可以使用MAX()函数:同样,当需要了解一列中的最小值时,可以使用MIN()函数.语法如下. SELECT MAX (column_name) / MIN ...
- C语言求两个函数中的较大者的MAX函数
//求两个函数中的较大者的MAX函数 #include <stdio.h> int main(int argc, const char * argv[]) { printf("i ...
- MAX函数和GROUP BY 语句一起使用的一个误区
使用MAX 函数和 GROUP 的时候会有不可预料的数据被SELECT 出来.下面举个简单的例子:想知道每个SCOREID 的 数学成绩最高的分数. 表信息:/*DDL Information For ...
- matlab 中max函数用法
Matlab中max函数在矩阵中求函数大小的实例如下:(1)C = max(A)返回一个数组各不同维中的最大元素.如果A是一个向量,max(A)返回A中的最大元素.如果A是一个矩阵,max(A)将A的 ...
- SQL MAX() 函数
MAX() 函数 MAX 函数返回一列中的最大值.NULL 值不包括在计算中. SQL MAX() 语法 SELECT MAX(column_name) FROM table_name 注释:MIN ...
- SQL- 行转列,多行转多列 - max 函数
效果如图,把同一个 code, 按 cate 列相同行的进行合并后分两行,把mode 每种类型转换成 列名 ,主要用到了 max 函数,很实用 if exists(select * from temp ...
随机推荐
- Android NDK 环境搭建 + 测试例程(转)
懒得废话一大堆概念,关于ADT.NDK的概念要是你不懂,怎么会搜到这里来?所以你只需要根据下面的步骤来,就可以完成NDK环境搭建了. 步骤:(假设你未安装任何相关开发工具,如果已经安装了,就可以跳过) ...
- Java POI 导出excel表
1.首先下载poi-3.6-20091214.jar,下载地址如下: http://download.csdn.net/detail/evangel_z/3895051 2.Student.java ...
- 创建一个流(Stream)可以让Bitmap或Image保存到流里面(转)
创建一个流(Stream)可以让Bitmap或Image使用save方法将已经在bitmap上生成的图像 保存到流里面?不需要直接在硬盘上生成文件 -------------------------- ...
- java获取对象属性类型、属性名称、属性值 【转】
/** * 根据属性名获取属性值 * */ private Object getFieldValueByName(String fieldName, Object o) { try { String ...
- merge into Oracle里的 saveOrUapdate
1.初始数据: SQL> select * from a; ID NAME ---------------------- ---------------------- 1 1 2 1 3 1 4 ...
- Delphi 动态改变Rzsplitter的Orientation(方向)属性
效果图: 原先不知道,弄了半天都改不了RzSplitter.Orientation = orHorizontal / orVertical 然后去查该组件的源代码,原来Orientation不是在Rz ...
- protocol buffer VS 2013编译出错
protocol buffer 在VS2013编译会出现以下错误. 解决办法 把宏加上, 问题解决. 注: 该错误只出现在Debug版本.
- 【USACO 2.4.2】穿越栅栏
[描述] 农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫.幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口.更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找 ...
- java解析JSON (使用net.sf.json)
例如JSON字符串str如下: { "data": [ { "basic_title": "运筹帷幄因 ...
- javascript 常用array类型方法
concat:基于当前数组中的所有项创建一个新数据,会创建当前数组一个副本,然后将接受到的参数放到数组末尾,最后返回新数组.如果没有参数,则复制当前数组并返回副本. slice:基于当前数组中一个或多 ...