C符号之逻辑运算符、左移与右移、…

来源:互联网 发布:淘宝同款排除工具 编辑:程序博客网 时间:2024/06/01 16:27
本篇为转载,写得不错,分享之。

本篇文章将总结C中一些比较有趣的符号

逻辑运算符:“ ||” 与 “ &&” 是比较常用的逻辑运算符,分别是   

或(||):双目运算符。两者中任一为真即为真。

与( &&):双目运算符。两者都为真时才为真,任一为假即为假。

但是,这两个运算符都有一个有趣的地方。请看下面的例子:

 

[cpp] viewplaincopyprint?
  1. int    a=0, b=1;  
  2. ifb++ || ++a  
  3.  
  4.      printf("%d"a);  
  5.  

 

 

编译通过。运行结果是  0 。

这就奇怪了。  || “ 不是判断两个数是否为真吗?没错,确实是判断了,但是这里只是判断了前面的一个,因为检查到前者为真了,所以后者就不检查了,不检查也即不执行了。因为  ||只需两者任一为真就为真。所以直接执行判断前者,如果为假才再去执行后者进行判断。哈哈,是不是很聪明呢?(其实是太懒了)

同样,对于 ” && “ 也是这样。也可以试试运行下面这例子。 

 

[cpp] viewplaincopyprint?
  1. int    a=0, b=1;  
  2. if&& ++b)  
  3.  
  4.      printf("%d"b);  
  5.   

 

 


左移(<<)与右移(>>):

两者都为双目运算符。两者在移位时都遵循各自的特点。

“<<”:移动时,高位丢弃,地位补0。

“>>”:移动时,对于有符号数,其符号位将随同移动。当为整数时,最高位补0;而为负数时,符号位为1,最高位是补 0 或是补 1 取决于编译系统的规定

在这个运算符的学习过程中,我结合了前面的大端、小端模式。这是计算机存储数据的模式。通过测试后,本人的计算机为小端模式。并结合小端模式和左移、右移运算符的知识。发觉数据存储模式并不会影响左移、右移运算符的操作。这就衍生了一个新的问题,大端、小端模式对什么有影响?在什么情况下有影响?

下面来看看一个例子:

 

[cpp] viewplaincopyprint?
  1. 0x01<<2+3  
不要惊讶,结果是32,因为优先级的问题,+比 << 优先级要高

 

那这两个呢?

 

[cpp] viewplaincopyprint?
  1. 0x01<<2+30;  
  2. 0x01<<2-3;  
编译运行,是不行的,因为

 

 

  1. 左移和右移的位数是不能超出数据的长度
  2. 也不能小于0

 


自增(++)与自减(— —):

a ++:先用再加

++ a:先加再用

自减运算符同样。

这两点太基础了,也太普通了。下面我们来看点有意思点的。

 

[cpp] viewplaincopyprint?
  1. int    a=1, b=1;  
  2. printf("%d"a+++b);   //语句 1  
语句1 是什么意思?呵呵,这里就要说说 贪心法 了。

 

 

C语言有这样一个规则:每一个符号应该包含尽可能多的字符。也就是说,编译器将程序分解成符号的方法是,从左到右一个一个字符的读入,如果该字符可能组成一个符号,那么再读入下一个字符时,判断已经读入的两个字符组成的字符串是否可能是一个符号的组成部分;如果可能,继续读入下一个字符,重复上述判断,直到读入的字符组成的字符串已不再可能组成一个有意义的符号。这个处理的策略被称为 “贪心法”

现在我们知道C语言有这样的规则,对 语句1 的意思也有明白了。没错,a+++b 等于a++ +b

如果是换成这样子呢?a+++++b?又会怎样?

编译不通过。我们换种写法,改为a+++++b。这个时候编译通过了!这里我们再次根据”贪心法“去思考这个问题。就恍然大悟了!

这里也总结了一件事,理论还是理论。即使你明白,理解。但是没有经过实践的话,是不会掌握的!就如 a+++++b 一样,你不去实践,按照理论去想的话。肯定能编译通过的,但是你实践了,才知道是错误的。

0 0
原创粉丝点击