3.10.1 认识if语句
尽管函数的调用者传递什么,被调用的函数只能被动接受,但如果真的传入了不恰当的值,在函数内部还是应该做点什么,而不是将错就错,把事情干得一塌糊涂。为了做到这一点,就得对参数的值进行检查和判断,函数cusum用来计算1到N的累加和,原则上返回值不应该小于1。利用这个特点,如果调用者传入的值超过了我们容许的范围,就直接返回0,否则就可以进行实际的累加过程。调用者可以检查函数的返回值,如果发现是0,它就知道本次累加失败了。
为此,我们就要使用C语言提供的if语句。在C语言里,语句用于执行动作,控制程序的执行流程,使用while语句可以循环往复地执行同一段代码,而if语句则有选择地执行或者不执行某些代码,因此它又称为选择语句。以下是if语句的语法。
if(表达式)语句
或者
if(表达式)语句else语句
如上所示,if语句有两种形式,第一种形式由关键字“if”引导,然后是一对圆括号和由它括住的表达式,这是if语句的控制表达式,后面是语句。第二种形式的前半部分和第一种形式相同,但添加了一个由关键字“else”引导的部分,称为else子句。
如图3-3所示,if语句的执行过程是这样的:先求值控制表达式,再根据该表达式的值,以及是否有else子句进入相应的分支进行处理。
图3-3 if语句的执行流程
如下面的代码所示,函数cusum内使用了if语句,if语句的控制表达式是一个关系表达式r>1000000000。在执行期间,表达式r执行左值转换,并与1000000000进行比较。如果变量r的值大于1000000000,关系成立,控制表达式的值为1,执行语句
return 0;
这将导致程序的执行离开cusum函数,直接返回到调用者,并将0作为返回值。在英语里,“else”是“否则……”的意思,因此,如果上述关系不成立,则执行语句
while(r)sum += r --;
这是一个while语句,它已经是你的老朋友了,我相信用不着再多说什么。
unsigned long long int cusum(unsigned long long int r) { unsigned long long int sum = 0; if(r > 1000000000) return 0; else while(r)sum += r --; return sum; }
就像while语句的循环体一样,如果组成if语句的那两个语句由多条组成,则必须使用复合语句。尽管在这里并不需要使用复合语句,但那些讲究程序设计规范的人坚持认为上述if语句应该写成这样:
if(r > 1000000000) { return 0; } else { while(r)
{ sum += r --; } }
他们的理由听起来也颇有道理:如果程序的功能需要扩充,那么这种格式修改起来十分方便。问题在于,把简单的流程写得令人眼花缭乱可能违背了使程序易读的初衷。
从语法上来看,if语句的else子句是可选的,如果不需要可以省略。在函数cusum的以下版本中,if语句省略了else子句,但程序的功能没有变化。
unsigned long long int cusum(unsigned long long int r) { unsigned long long int sum = 0; if(r > 1000000000)return 0; while(r)sum += r --; return sum; }
显然,在这里,if语句的作用仅仅是在变量r的值大于1000000000时,将控制直接返回到函数的调用者;否则控制表达式的结果为0,于是离开if语句,直接往后执行while语句,但while语句并不是if语句的组成部分。
如果希望while语句成为if语句的一部分(子句),则可以修改if语句的控制表达式,把它改成r<= 1000000000,如以下新版的cusum函数所示。
unsigned long long int cusum(unsigned long long int r) { unsigned long long int sum = 0; if(r <= 1000000000)while(r)sum += r --; return sum; }
这里,如果变量r的值小于等于1000000000,则控制表达式r<= 1000000000的值不为0,这将会执行后面的while语句,否则不会执行。最后的return语句总是要被执行的,如果while语句未执行,返回变量sum的初值0;如果while语句被执行,则返回变量sum的新值(累加结果)。