学习心得(code)

superlong@CoreCoder

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  74 Posts :: 0 Stories :: 5 Comments :: 0 Trackbacks

公告

文字可能放在http://blog.csdn.net/superlong100,此处存放代码

常用链接

留言簿(4)

我参与的团队

搜索

  •  

最新随笔

最新评论

  • 1. re: Poj 1279
  • 对于一个凹多边形用叉积计算面积 后能根据结果的正负来判断给的点集的时针方向?
  • --bsshanghai
  • 2. re: Poj 3691
  • 你写的这个get_fail() 好像并是真正的get_fail,也是说fail指向的串并不是当前结点的子串。为什么要这样弄呢?
  • --acmer1183
  • 3. re: HDU2295[未登录]
  • 这个是IDA* 也就是迭代加深@ylfdrib
  • --superlong
  • 4. re: HDU2295
  • 评论内容较长,点击标题查看
  • --ylfdrib
  • 5. re: HOJ 11482
  • 呵呵..把代码发在这里很不错..以后我也试试...百度的编辑器太烂了....
  • --csuft1

阅读排行榜

评论排行榜

Clang 宏定义初探(一)

的定义方法是#define
那么在什么场景下需要用到宏呢?遇到一些重复的东西,简单的有 for(i = 0; i < n; i ++) 之类的,为了减少繁琐的编码,可能使用
#define FO(i,N) for(i=0;i<N;i++)
为了增强可读性,比如说设置一个数组常亮大小,可以使用
#define N 1001
宏看起来感觉很好用,但是潜藏了很多问题,在实际使用中需要小心谨慎(当然带来大部分问题的,还是编码者自己或者合作方)。
如,现在要求两个数的最小值,最初会写出如下宏:
#define MIN(A,B) A<B?A:B
正常情况下也是可以使用无误的:
1 #include <stdio.h>
#define MIN(A,B) A<B?A:B
int main()
4 {
5     int a =5, b =6;
6     printf("%d", MIN(a, b));
7 }
然而,当你发布你的代码或者很久以后自己再去调用时,可能写成:
MIN(a<4?a:5, b)
看起来也没啥问题,实际执行一下发现,结果是5,偏离预期!事实上,宏即使单纯的代码展开,当你展开上面的式子之后会发现,实际执行的代码是
a<4?a:5<b?a<4?a:5:b
对于一直用括号来解决优先级问题的我来说,这种展开完全无法理解,于是参看了内核代码,发现更安全的写法为:
#define MIN(A,B) (A)<(B)?(A):(B)
这种写法规避了令人厌恶的优先级问题!本以为这样就完成了一个安全的宏定义,但是事实上还有其他问题!
float a = 1.0f;
float b = MIN(a++, 1.5f);
printf("a=%f, b=%f",a,b);
神秘的a++,同样按照刚才的思路展开,因为宏里面会有两次A的展开,所以a++将被执行两次,再次偏离预期。对于这种情况,我们需要用到一个GNU C的赋值扩展,即使用({...})的形式。这种形式的语句可以类似shell,在顺次执行之后,会将最后一次的表达式的赋值作为返回。举个简单的例子,下面的代码执行完毕后a的值为3,而且b和c只存在于大括号限定的代码域中:
int a = ({
    int b = 1;
    int c = 2;
    b + c;
});
结果是// => a is 3
基于这种特性,我们可以在宏里面为每个传入的参数进行一个拷贝,然后再对拷贝后的参数进行实际的比较运算,那么最终实现了一个比较安全的最小值比较的宏定义:
#define  min(x,y)  ({                   \  
    typeof(x)  __min1 = (x);        \  
    typeof(y) __min2 = (y);             \  
    (void)  (& __min1 == & __min2);     \  
    __min1 < __min2  ? __min1 :min2})  
最后这一步跳跃有点大了,首先是 typeof 作用是得到参数的类型,其次是(void) (& __min1 == & __min2);  这个神秘的写法是为了验证二者的类型是否一致,当然外侧我们确实用了GNU的扩展({...})。
写到这里,涉及到了另外两个问题,GNU扩展是啥?另外我们用宏是为了节省代码,同时为了省去一些小函数的多次重复调用的参数入栈降低性能的问题,那么内联函数也有这样的效果,什么是内联函数呢?
posted on 2016-03-08 08:44 superlong 阅读(837) 评论(0)  编辑 收藏 引用 所属分类: C

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理