首页 > 试题广场 >

写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。

[问答题]
写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。另外,当你写下面的代码时会发生什么事?  
least = MIN(*p++, b);  
宏的参数和整个宏都要用括号括起来。
发表于 2017-05-15 17:03:10 回复(0)
更多回答
推荐
解答:  
#define MIN(A,B) ((A) <= (B) ? (A) : (B))   
MIN(*p++, b)会产生宏的副作用  
剖析:  
这个面试题主要考查面试者对宏定义的使用,宏定义可以实现类似于函数的功能,但是它终归不是函数,而宏定义中括弧中的“参数”也不是真的参数,在宏展开的时候对“参数”进行的是一对一的替换。  
程序员对宏定义的使用要非常小心,特别要注意两个问题:  
(1)谨慎地将宏定义中的“参数”和整个宏用用括弧括起来。所以,严格地讲,下述解答:  
#define MIN(A,B) (A) <= (B) ? (A) : (B) 
#define MIN(A,B) (A <= B ? A : B ) 
都应判0分;  
(2)防止宏的副作用。  
宏定义#define MIN(A,B) ((A) <= (B) ? (A) : (B))对MIN(*p++, b)的作用结果是:  
((*p++) <= (b) ? (*p++) : (b))   
这个表达式会产生副作用,指针p会作2次++自增操作。  
除此之外,另一个应该判0分的解答是:  
#define MIN(A,B) ((A) <= (B) ? (A) : (B));  
这个解答在宏定义的后面加“;”,显示编写者对宏的概念模糊不清,只能被无情地判0分并被面试官淘汰。  
编辑于 2015-12-11 11:10:28 回复(10)
NWU头像 NWU
之所以对宏的定义不能加分号是因为宏定义只是用宏名对一个字符串进行简单的替换,如果在宏定义命令后加了分号,将会连同分号一起进行置换。
发表于 2015-12-22 19:45:41 回复(0)
Linux内核经典宏定义,了解下 #define MIN(a, b) ({\ typeof(a) _MIN1 = (a);\ typeof(b) _MIN2 = (b);\ (void)(&amp;_MIN1 == &amp;_MIN2);\ _MIN1 &lt; _MIN2 ? _MIN1 : _MIN2; }) 这个宏定义用到了typeof,是GNUC的一个扩展使用。 博文了解下:《【Linux内核】从小小的宏定义窥探Linux内核的精妙设计》, https://blog.csdn.net/szullc/article/details/84779352
编辑于 2019-03-01 20:34:59 回复(0)
首先MIN的宏函数写法
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
当写入下面的代码后:
least = MIN(*p++, b);  
预编译为:
least = ((*p++) < b) ? (*p++) : (b)
如果p指向的值小于b,返回的是p后面的一个值;
如果p指向的值大于b,返回的则是b
发表于 2017-07-30 17:01:21 回复(0)
这个问题很***,明明可以写出避免自加运算导致出错的宏定义啊,什么叫“会出什么问题”?出了问题这个宏就写得不对。具体怎么避免,百度即知。
发表于 2017-10-27 02:26:56 回复(0)
只是针对这道题目宏定义后面不能加分号,谁说宏定义都不能加分号的。。。好多库后面都会加分号的,为了方便书写一些语句的时候
发表于 2022-08-22 03:41:45 回复(0)
宏定义后面没有分号

发表于 2018-10-22 17:04:47 回复(0)
不要用改变变量的调用方法,来调用宏定义,会有副作用
#define宏后面没有分号;
发表于 2017-06-12 10:19:50 回复(0)
宏是替换,所以使劲儿加括号
发表于 2016-04-13 13:33:51 回复(0)

宏整个表达式和参数都要加括号,因为是字符串替换

宏后没分号

宏中参数不能有自加等操作

发表于 2018-07-05 00:01:00 回复(1)
<p>#define MIN(x,y) (((x) &lt; (y) ? (x) : (y))</p>
发表于 2020-05-05 12:45:55 回复(0)

应该是自增和自减的副作用,而不是宏的,宏只会照定义在使用处替换,相当于依葫芦拷贝。

C中以一个分号以及while中的判断语句为一个完整的表示式,如果一个表达式中某个变量自增出现2次,C只会保证在整个表达式结束后该变量会增加2次,而在执行中是否增加或者什么时候增加都是不确定的。

发表于 2020-03-26 09:54:22 回复(0)

#define MIN(m,n) ((m)<(n) ? (m):(n))

编辑于 2019-12-26 09:34:24 回复(0)
当在宏中出现函数作参数替换时,如果函数本身值会发生变换,那么结果会改变,处理时会将函数调用两次。另外,宏后不加分号。
发表于 2019-12-10 09:59:48 回复(0)

#define ((A)?(B):A,B)

发表于 2019-10-21 22:39:52 回复(0)
#define Min(a,b) ((a)<=(b)?(a):(b))
编辑于 2019-07-04 23:06:39 回复(0)
#define MIN(A,B) ( (A)<= (B) ? (A) : (B) )
编辑于 2019-06-21 12:23:23 回复(0)
#define MIN(A,B) ((A)<= (B) ? (A): (B))
发表于 2019-03-21 19:02:14 回复(0)
宏定义是每个参数和整个宏都需要有括号,然后进行一对一的替换
发表于 2018-11-29 09:54:13 回复(0)
宏定义#define MIN(A,B) ((A) <= (B) ? (A) : (B))对MIN(*p++, b)会产生宏的副作用,指针p会做2次自增操作。

#define MIN(A,B) ((A) <= (B) ? (A) : (B))
((*p++) <= (b) ? (*p++) : (b)) 
发表于 2017-05-02 10:33:31 回复(1)