游戏开发论坛

 找回密码
 立即注册
搜索
查看: 10715|回复: 3

C语言基本功教程系列(2) - if 语句

[复制链接]

27

主题

179

帖子

259

积分

中级会员

Rank: 3Rank: 3

积分
259
发表于 2006-10-8 15:15:00 | 显示全部楼层 |阅读模式
趁周末再写一章。今天就介绍下if语句

if语句很简单,相信大家都会,但是确有很多值得注意的。 首先来说一下code style的问题。

=========不好的风格===========
if( (x +4-y * 25) > 10 || y > 1023 || GetSomething())
{
   ....
}

=========好的风格============
if( (x +4-y * 25) > 10
    || y > 1023
    || GetSomething() )
{
   ....
}
相信大家能看出来第2段代码的时候要比第1段代码容易读的多。

if语句虽然简单,但是涉及到CPU的branch prediction的问题。简单的说, CPU有个指令缓存,会预先把一部分代码读到缓存中等待稍后执行。当CPU遇到 if语句的时候, 会把条件判断为true的那段代码读到缓存中,然后对if(条件判断)中的条件判断语句进行运算。如果运算结果是false,那么CPU就会重新从内存中载入false的代码,在这期间大部分CPU时间会被浪费点。

所以在写if语句的时候,一定要把最容易成立的条件放在最前面进行判断。 比如:

======错误的写法=======
if( (float)rand() / RAND_MAX < 0.2 )  //只有20%的可能运行if部分
{
    // 被读入到指令缓存的部分。
}
======正确的写法=======
if( (float)rand() / RAND_MAX > 0.2 ) //有80%的可能运行if部分。
{
    // 被读入到指令缓存的部分。
}

if语句另外一个需要注意的地方是在进行多重条件判断的时候,要安排好顺序。比如:

if (  (float)rand() / RAND_MAX < 0.4
      && (float)rand() / RAND_MAX < 0.3
      && (float)rand() / RAND_MAX < 0.2 )
{
    ......
}
根据C语言的规则(这点不同于Pascal),如果第一个条件(rand() / RAND_MAX < 0.4)不成立,那么就不会运行第2和第3个条件,而直接跳转。 所以应该把最难成立的条件放在第一的位置上,正确的代码为:
if (  (float)rand() / RAND_MAX < 0.2     // 只有%20的可能
      && (float)rand() / RAND_MAX < 0.3
      && (float)rand() / RAND_MAX < 0.4 )
{
    ......
}
由于编译器并无法计算和统计每种条件成立的可能性,只能靠大家手动的调整来提高代码的效率。

最后是if有一种技术叫做binary branch,举个简单的例子,代码如下:

int x;
if( x == 1)
{

}
else if( x == 2)
{

}
else if( x == 3)
{

}
else if( x == 4)
{

}
对付这段代码,可以用switch来解决,也可以用binary branch,修改后的代码如下:
if( x <= 2)
{
     if( x == 1)
     {...}
     else
     {...}
}
else
{
     if( x == 3)
     {...}
     else
     {...}
}
如果判断的情况复杂一点,编译器就没有优化的能力,需要考大家自己动手啦。



0

主题

5

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2008-3-18 16:23:00 | 显示全部楼层

Re:C语言基本功教程系列(2) - if 语句

想到以前看到的一个C语言的小应用,在C语言中布尔变量TRUE为非零数值,FALSE为0,所以可以用这点把分支语句转成表达式。

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2008-3-27 09:24:00 | 显示全部楼层

Re:C语言基本功教程系列(2) - if 语句

使用函数指针的数组,时间复杂度 O(n^0)

27

主题

179

帖子

259

积分

中级会员

Rank: 3Rank: 3

积分
259
 楼主| 发表于 2008-3-28 04:28:00 | 显示全部楼层

Re:C语言基本功教程系列(2) - if 语句

这坟挖的。说实话,这些技巧也就是在 386, 486 那些10多年前的机器上还有些价值。对于现在的机器来说,这点速度的提升已经没什么大用了。不过对于理解CPU的结构有些帮助.

顺便说下,如果使用switch语句,并且所有的判断条件是能够用0到一个整数表示, 比如:

switch( num )
{
case 0:
   ...
   break;

case 1:
   ...
   break;

case 2:
   ...
   break;
}

或者
enum TYPE {
    TYPE1,
    TYPE2,
    TYPE3,
};

switch( Type )
{
  case TYPE1:
     ...
  case TYPE2:
     ...
  case TYPE3:
     ...
}

那么switch会被优化成使用函数指针表进行跳转, cost是 o(1)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-20 14:17

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表