《编写高质量代码:改善c程序代码的125个建议》——建议19:避免使用嵌套的“?:”

简介:

本节书摘来自华章计算机《编写高质量代码:改善c程序代码的125个建议》一书中的第3章,建议19,作者:马 伟 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

建议19:避免使用嵌套的“?:”

在C语言中,“?:”运算符是if/else语句的另外一种表示形式,其一般形式如下所示:

Exp1 ? Exp2 : Exp3

其中,Exp1、Exp2 与 Exp3都是表达式。程序首先对Exp1 求值,如果 Exp1 的值为真时,就对Exp2 求值并将其求值结果作为整个问号表达式的值;否则,就对Exp3 求值并将其求值结果作为整个问号表达式的值。
由于问号表达式语法的简洁性,因此我们经常看到一些程序员在做判断时只用“?:”,而从不使用if/else语句。如下面的示例代码所示:

unsigned int f( int x)
{
    return x>=1?1:0;    
}

很显然,相对于if/else语句,这样的代码看起来更加简洁明了。但是,如果我们嵌套使用“?:”,那就不一样了。如下面的示例代码所示:

unsigned int f(unsigned int x)
{
    return( (x<=1)?(1-x):(x==4)?2:(x+1) );
}

在上面的代码中,嵌套了两层“?:”,它实际等效于下面的代码:

unsigned int f(unsigned int x)
{
    unsigned temp;
    if(x <= 1)
    {
            if(x != 0)
            {
                    temp = 0;
            }
            else
            {
                    temp = 1;
            }
    }
    else
    {
            if(x == 4)    
            {
                    temp = 2;
            }
            else
            {
                    temp = x + 1;
            }
    }
    return temp;
}

从上面的代码中可以看出,尽管嵌套使用“?:”可以使代码变得简洁,但代码的可读性却因此降低了不少。这个时候有的程序员或许会说,嵌套使用“?:”不仅使代码简洁,更重要的是它比if/else语句能够产生更加高效的代码。但实际情况并非如此,有兴趣的读者不妨试一试下面的代码,对两者做个比较。

unsigned int f(unsigned int x)
{
    unsigned temp;
    if( x <= 1 )
    {
            temp = 0;    
            if( x == 0 )
            {
                    temp = 1;
            }
    }
    else
    {
            temp = 2;    
            if( x != 4 )
            {
                    temp = x + 1;
            }
    }
    return temp ;
}

其实,使用“?:”运算符所存在的问题是:由于它很简单,容易使用,看起来好像是产生高效代码的理想方法。因此,程序员就不再寻找更好的解决方法了。更糟糕的是,有些程序员会将if/else语句全部转换为“?:”来获得所谓的高效解决方案。而实际上“?:”并不比if/else语句好,它们所产生的汇编代码也基本相同。
因此,为了能够提高程序的执行效率,我们应该将时间花在寻求可替代的高效算法上,而不是一味地追求以某个稍微不同的方式来实现同一个算法上。例如,我们可以将上面的代码修改成下面这种更直接的实现方法:

unsigned int f(unsigned int x)
{
    assert( x >= 0 && x <= 4 );
    if( x == 1 )     
    {
            return 0 ;
    }
    if( x == 4 )    
    {
            return 2 ;
    }
    return x + 1 ;        
}

甚至,我们还可以使用下面的列表方式来实现上面的示例程序,如下面的代码所示:

unsigned int f(unsigned int x)
{
    assert( x >= 0 && x <= 4 );
    static const unsigned temp[] ={1,0,3,4,2 };
    return  temp[x] ;
}
相关文章
|
存储 C语言
《编写高质量代码:改善c程序代码的125个建议》—— 导读
众所周知,C语言是一门既具有高级语言特点,又有汇编语言特点的通用计算机编程语言,无论是操作系统(如Microsoft Windows、Mac OS X、Linux和UNIX等)、嵌入式系统与普通应用软件,还是目前流行的移动智能设备开发,随处都可以看见它依然矫健的身影。
1768 0