C语言非常道
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.10.4 摇摆的else子句

依据语法,一个if语句是由关键字“if”、圆括号、表达式和其他语句组成,这里的“其他语句”可以是任何语句,包括另一个if语句。

如果if语句的子句也是一个if语句,那可就花哨了。为了演示这种情况,我们编写了一个新版的cusum函数,它里面的if语句就是这种情况。在这个新版的函数里,if语句首先检查变量r的值是否为零,如果为零则直接结束函数的执行并返回到调用者;否则的话,它的else子句检查r的值是否大于1000000000。如果条件成立,则也结束函数的执行,将控制返回到调用者;如果不成立,则执行while语句,开始累加过程。

                unsigned long long int cusum(unsigned long long int r)
                {
                    unsigned long long int sum = 0;

                    if(r == 0)return 0;
                    else
                      if(r > 1000000000)return 0;
                      else while(r)sum += r --;

                    return sum;
                }

在这里有两个if语句,但第二个if语句是另一个if语句的组成部分。如图3-4所示,第一个被框住的return语句是第一个if语句的第一个子句;第二个被框住部分尽管也是if语句,但它整体上是第一个if语句的else子句。

图3-4 规范的if语句在语法上是没有歧义的

但是,如果if语句嵌套不当,则容易使人迷惑。比如下面的例子,你来说说,里面的else子句到底属于第一个if语句,还是属于第二个if语句?

                unsigned long long int cusum(unsigned long long int r)
                {
                    unsigned long long int sum = 0;
                    if(r > 0)
                        if(r <= 1000000000)
                          while(r)sum += r --;
                    else
                        sum = 0;

                    return sum;
                }

尽管从排版上来看,这个else子句属于第一个if语句,但真实的情况与排版无关。如图3-5所示,虽然被框住的部分是一个带有else子句的if语句,但它可以被认为是顶上那个if语句的子句(它没有else子句)。

图3-5 有歧义的if语句,这是它的第一种解读方式

然而,如图3-6所示,我们也可以认为else子句属于第一个if语句,第二个if语句没有else子句,且属于第一个if语句的第一个子句。

图3-6 有歧义的if语句,这是它的第二种解读方式

那么,到底哪种隶属关系才是正确的呢?C语言规定,一个else子句从属于离它最近的那个if语句。因此,这个else子句实际上是第二个if语句的一部分(这就是说图3-5才是正确的)。如果这并不是你所期望的,那就应该使用复合语句来明确隶属关系:

                    if(r > 0)
                    {
                        if(r <= 1000000000)
                          while(r)sum += r --;
                    }
                    else
                        sum = 0;