Chinaunix首页 | 论坛 | 博客
  • 博客访问: 988117
  • 博文数量: 158
  • 博客积分: 4380
  • 博客等级: 上校
  • 技术积分: 2367
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-21 10:45
文章分类

全部博文(158)

文章存档

2012年(158)

我的朋友

分类: C/C++

2012-11-23 16:21:47

看到这样的C/C++代码
int tmp; // 代码一
while( ... )
{
    tmp = a;
    a = b;
    b = tmp;
}
...
确实有点无语,连C#er都知道这样的写法不好,因为M$在《XXX》中告诉他们tmp将无法得到优化。看来C/C++高估了使用者的等级,其实也需要一些幼稚园的启蒙读物。
正确的写法应该是
while( ... ) // 代码二
{
    int tmp = a;
    a = b;
    b = tmp;
}
...
差别在于代码二明确告诉编译器tmp的全部作用,而代码一中编译器只能保守的认为tmp还没完,这段代码执行完毕之后tmp还可能需要被用到,所以必须将它的值保存下来。
一个是全部的信息,一个部分信息,任何人都能猜得出哪个更会被编译器优化好。
之所以谈到“优化”,因为写出代码一的人大抵是认为代码二中tmp频繁定义会影响运行效率,……,如果真是这样想,嗯,也情有可原,虽然错误,但属于经过大脑思考过的。

[题外话:本来草民的blog也就是小圈子中聊聊,原本宁静,但现在访客中也有很黄很暴力的^_^,所以我必须浪费一些笔墨,把文章补充很多废话,否则_-_]
不得不加上的废话1:古老的C语言,用到的变量必须提前声明(编译器可以直接得到需要的栈空间尺寸),所以代码必须写成代码一的形式。
我在21世纪说的C语言肯定默认是现在的C语言,所以如果用的不是C99,或代码是过去传承下来的,那自然不在我“口伐”的对象中。
不得不加上的废话2:大部分编译器都能把代码一也优化好。
是的,如果我在代码中加上1万个int i001; int i002;的定义,编译器也会将它们优化没,但我却无法跟老板说因为编译器……,所以你就让我加上1万个无用的定义玩玩吧。
不得不加上的废话3:或许有---虽然我不敢确定---这样的编译器,它能优化代码一,却不能优化代码二。
如果是这样,那么代码一属于编译器依赖性优化,对于这样的优化,一般的编码规范是:a.提供一份非编译器依赖的代码注释,即代码二。b.在文档或代码中指明为什么必须进行这步优化,它适用于哪个版本的哪个编译器。差不多类似这样
#ifdef XXX编译的aaa.bbb.ccc.dddd版本
代码一
#else
代码二
#endif
不得不加上的废话4:代码一改为 register int tmp; 就OK了。
同“不得不加上的废话2”,做正确的事,而不是把错误的事做正确。
不得不加上的废话5:不就是一个优化嘛,不值得浪费时间。
是的,可惜我说的不是优化,我只是拿优化来说事。代码二是自然而然的算法体现(她是一个代码自解释的算法),而代码一不是,代码一本身无法解释为什么int tmp会定义在域外。此帖声讨的是为什么有人要舍简单取复杂,舍清晰取晦涩?(当然如果是误认为代码一会优化得更好的人不在此列)。

阅读(1476) | 评论(9) | 转发(0) |
给主人留下些什么吧!~~

网友评论2012-11-23 16:22:50

aaa
之所以谈到“优化”,因为写出代码一的人大抵是认为代码二中tmp频繁定义会影响运行效率,……,如果真是这样想,嗯,也情有可原,虽然错误,但属于经过大脑思考过的。
---------------------------------------------
为什么这想法是错的?

网友评论2012-11-23 16:22:43

haha
回贴是一种美德

网友评论2012-11-23 16:22:36

周星星
那说明你的设计有问题,同“不得不加上的废话2”:做正确的事,而不是把错误的事做正确。

网友评论2012-11-23 16:22:28

新年好
不得不加上的废话6: 如果是一个临时对象,为了避免频繁的构造析构,还是放外面好些:)