我们都知道,&&是逻辑与, ||是逻辑或。对于这两个运算符,有下面的性质:
1 && 1 = 1; 1 && 0 = 0; 0 && 1 = 0; 0 && 0 = 0; 1 || 1 = 1; 1 || 0 = 1; 0 || 1 = 1; 0 || 0 = 0; |
出了这些基本的性质之外,额外需要注意的是,在C语言中,这两个运算符有如下的性质:
- && 的 优先级高于 ||。
- 这两个运算符都是短路(short circuit)操作符。什么是短路操作符呢?我们注意到,对于&&操作符来说,如果它的左操作数为false,则整个表达式一定为false,我们不需要再计算其右表达式,而C语言中确实也是这么做的。对于||情况也是一样的,如果其左操作数为true,则整个表达式一定为true,而不用计算其右表达式。这两个操作符只有在当左操作数不能决定整个表达式的值的时候才会计算右操作数。
让我们看如下代码:
#inlcude <stdio.h> int main(){ int a, b; a = 1 || 1 && 0; b = (1 || 1) && 0; printf("%d\n",a); printf("%d\n", b); } |
这段代码的输出是什么呢?大家可以自己验证下,答案是a=1; b=0。
如下面代码:
#include <stdio.h> int func(); //计算一些事情并返回一个值 int main(){ 0 && func(); //func()不会被计算 1 || func(); //func()不会被计算 1 && func(); //func()会被计算 0 || func(); //func()会被计算 } |
下面我们来看一道题目,是EMC某年的笔试题:
题目:
函数声明如下:
int func(int i, int N); |
其中,i<=N, 功能输出i递增到N再递减到i的整数,每行输出一个数。比如func(1, 5)的输出是:
1 2 3 4 5 4 3 2 1 |
要求:
- 函数中只能有一个语句,即1个分号。
- 不能使用do while until goto for if关键字,不能使用?:和逗号操作符。
- 唯一能使用的库函数为printf。
题目要求不能使用for等关键字,而且只有一个语句,那我们怎么才能实现一个循环递减和递增的数字序列呢?我们可以想到使用(递归),那么条件判断呢?这时,就可以利用&&和||的第二个性质来达到目的:
#include <stdio.h> int func(int i, int N){ return (i == N) && printf("%d\n",i) || printf("%d\n", i ) && func(i+1, N) && printf("%d\n", i); } |
另外,需要注意的是,尽管&&和||是短路操作符,但是“按位与/或”(&和|)却不是短路操作!
文中的 “func(i-1, N)” 应该是 func(1+1, N) 吧 ?
Sorry,打错了,func(i + 1, N)
@sagi 谢谢指正,果然错了!已经修正。
学习了~仿造写了一个:
#include
int func(int i, int N){
return (((i<=N && printf("%d\n",i)) && (func(i+1,N)||1)) && printf("%d\n",i));
}
@yjf512 呵呵,不错,学以致用!欢迎以后经常访问
Helpful blog, bookmarked the website with hopes to read more!
这些纯技巧的东西,一般没什么意义。。。。
混凝土天泵长度