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

    xiaoxiao2023-09-27  141

    本节书摘来自华章计算机《编写高质量代码:改善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] ; }
    最新回复(0)