3.10.5 认识逻辑与运算符
和逻辑或运算符||相对应的是“逻辑与”运算符&&,它表达逻辑上的相乘关系,对应于生活中的“并且”。和逻辑或运算符一样,逻辑与运算符&&需要一左一右两个操作数,例如1 && 0和5 && 6。
逻辑与运算符&&的结果是这样决定的:如果左操作数和右操作数的值都不为0,则该运算符的结果是1;否则,在任何其他情况下,该运算符的结果都为0。因此,表达式0 &&0的值是0;表达式0 && 9的值是0;表达式5 && 6的值是1。以下版本的cusum函数就使用了逻辑与运算符。
unsigned long long int cusum(unsigned long long int r)
{ unsigned long long int sum = 0; if(r ! = 0 && r <= 1000000000) { while(r)sum += r --; return sum; } return 0; }
以上,在if语句的控制表达式里,运算符<=的优先级最高,! =次之,&&最低。因此运算符&&的操作数分别是r ! = 0和r<= 1000000000,即,表达式r ! = 0 && r<=1000000000等价于(r ! = 0)&&(r<= 1000000000)。顺便说一句,运算符&&的优先级高于运算符||。
显然,表达式r ! = 0 && r<= 1000000000所描述的意思是“变量r的值不为0而且小于等于1000000000”。如果变量r的值符合这个条件,比如为2,则子表达式r ! =0描述的关系成立,运算符!=的值是1;子表达式r<= 1000000000所描述的关系也成立,运算符<=的值也是1,于是运算符&&的值是1,执行if语句的第一个子句(复合语句)。这个子句首先完成累加过程,然后直接用return语句结束当前函数的执行,将控制返回到调用者,返回值是累加后的结果。
如果if语句的控制表达式计算出一个零值,则程序的执行直接离开if语句,执行后面的
return 0;
这就与前面不一样了。先前版本的cusum函数在最后都返回表达式sum的值,但这次呢,只有在传入的参数值不符合条件时才会执行最后的这个return语句,所以它就应该返回一个零值。
逻辑与表达式的求值具有短路效应,它总是先求值运算符&&的左操作数,如果左操作数的值为0,则不再求值右操作数,因为这样做是多余的。只有在左操作数的值为1时,才会继续求值右操作数。
C语言规定,如果运算符&&的右操作数会被求值(这意味着左操作数求值的结果为1),则在其左操作数的求值和右操作数的求值之间存在一个序列点。换句话说,在求值右操作数之前,左操作数的值计算和副作用已经全部完成。
这就是说,如果标识符n被声明为指示一个整数类型的变量,则表达式n ++ && n的求值不是未定义的行为。因为,在求值表达式n时,表达式n ++的值计算和副作用已经完成,表达式n的值是递增之后的新值;在求值表达式n ++时,表达式n的求值还没有开始。