C语言中各种运算类型全面总结
目录
- 一、概述
- 二、四则运算
- 三、关系运算
- 四、逻辑运算与位运算
- 五、深度剖析位运算
一、概述
C语言中支持下面4种类型的运算
运算类型 | 运算符 |
四则运算 | +,-,*,/,% |
关系运算 | <,>,<=,>=,==,!= |
逻辑运算 | &&,||,! |
位运算 | &,|,^,>>,<<,~ |
二、四则运算
(+,-,*,/,%)
- 就是数学中的加,减,乘,除等运算
- 遵循先乘除后加减的运算优先级
- 可以使用括号改变运算顺序
注意:
C语言中的除法运算,其除数不能为0
下面通过一段程序感受一下:
#include <stdio.h> int main() { int a = 5; int b = 2; double c = 3; c = a / b; printf("c = %f\n", c); c = a % b; printf("c = %f\n", c); return 0; }
下面为输出结果:
通过上面的代码,可以得到一些小结论:
- 整型数的除法运算结果会舍弃小数部分
- 取余(%)运算也是一种除法运算,结果为余数
- 浮点数不能进行取余运算
三、关系运算
(<,>,<=,>=,==,!=)
- 比较两个值大小关系或相等关系的运算
- 比较的结果为逻辑值: 真(1),假(0)
- 可以使用括号()改变关系运算的顺序
如上面的图片所示,c 的值就为0
下面通过一段代码,感受一下:
#include <stdio.h> int main() { int a = 1; int b = 2; int c = 3; c = a != b; printf("c = %d\n", c); c = a - b >= a + b; printf("c = %d\n", c); c = (a < b) + (c < b); printf("c = %d\n", c); return 0; }
下面为输出结果:
小技巧:如果不同类型的运算同时出现在一个表达式中,那么尽量使用括号()指明运算顺序。
运算优先级(优先级:四则运算 > 关系运算 > 赋值操作)
四则运算
- 正负号 > 乘除运算 > 加减运算
关系运算
- 大小比较运算 > 相等比较运算
赋值操作
下面看一段代码,深入感受一下运算优先级:
#include <stdio.h> int main() { int a = 1; int b = 2; int c = 0; c = a != b + a * b; printf("c = %d\n", c); return 0; }
下面为输出结果,可以看出,c 的输出结果为1,为什么为1呢?这是由于乘法优先级大于加法优先级大于关系运算优先级,所以程序执行过程是这样,先计算 a * b,然后将 a * b 的结果 2 加上 b,得到4,最后再比较 a != 4,得到的结果当然为1啦,我们还可以通过反汇编来观察代码的执行过程。
c = a != b + a * b的汇编代码
所以如果想得到a != b 再加上a * b的结果,一定要记得加括号,如下:
#include <stdio.h> int main() { int a = 1; int b = 2; int c = 0; c = (a != b) + (a * b); printf("c = %d\n", c); return 0; }
这样才能得到正确结果,如下所示:
小结:
- 整型数除法有两种:取商(/),取余(%)
- 浮点数除法与数学中除法运算相同,结果为浮点数
- 不同运算的优先级不同,可使用括号改变运算优先级
- 同一个表达式中应避免不同的运算类型(四则运算,关系运算)
四、逻辑运算与位运算
逻辑运算(&&,ll,!)
- 逻辑运算的参与者为逻辑值(真或假)
- 任何非零值在逻辑运算中都为真
- 任何零值在逻辑运算中都为假
左操作数 | 右操作数 | 结果 |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
左操作数 | 右操作数 | 结果 |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
逻辑运算中的短路法则
对于&&运算
- 从左向右进行,如果有一个操作数为假,则整个表达式为假
- 第一个为假的操作数之后的其它操作数不再计算
对于||运算
- 从左向右进行,如果有一个操作数为真,则整个表达式为真
- 第一个为真的操作数之后的其它操作数不再计算
取非运算(!)
单目运算(只需要一个操作数),运算结果为逻辑值
- 对真值取非的结果为假
- 对假值取非得结果为真
话不多说,上代码:
#include <stdio.h> int main() { int a = 1; int b = 2; int c = 0; c = a && b; printf("c = %d\n", c); c = !(a - b) || (c < b); printf("c = %d\n", c); c = 10000; c = !!c; printf("c = %d\n", c); return 0; }
下面为运行结果:
位运算(&,|,~,^,<<,>>)
- 直接对数据的二进制位进行操作
- 位运算的基本单位是二进制位,所以也是一种0和1的操作
- 可以使用括号()改变位运算的运算顺序
- 位运算的操作数只能是整型数(浮点数不能直接进行位运算)
运算符 | 含义 | 示例 | 优先级 |
~ | 按位求反 | ~0101 -> 1010 | 1(高) |
<< | 左移:高位移出,低位补0 | 0011 << 1 -> 0110 | 2 |
>> | 右移:低位移出,高位补符号位 | 0101 >> 2 -> 0001 | 2 |
& | 按位与 | 0111 & 1100 -> 0100 | 3 |
^ | 按位异或:相同为0,不同为1 | 0111 ^ 1100 -> 1011 | 4 |
| | 按位或 | 0111 | 1100 -> 1111 | 5(低) |
注:
1.按位与和逻辑与的计算法相同:两者为1,结果为1,否则为0
2.按位或和逻辑或的计算法相同:两者为0,结果为0,否则为1
位运算实例
- 将整数5的第2个二进制位置1
- 将整数7的第4个二进制位取反
- 将整数2的最后两位取反
- 将整数15右移2位,再将第2个二进制位置0
- 设变量a的二进制数是10101101,若想通过运算a ^ b使得a的中间4位取反,其余位不变,则b的值是多少?
代码如下:
#include <stdio.h> int main() { printf("c = %d\n", 5 | 2); printf("c = %d\n", 7 ^ 8); printf("c = %d\n", 2 ^ 3); printf("c = %d\n", (15 >> 2) & 13); printf("c = %d\n", 173 ^ 60); return 0; }
运行结果如下:
这里需要特别注意:对某一位或者某几位取反可以用异或(^)运算,这在工程里常用!!!
运算优先级(优先级从上到下为由高到低)
- 正负号>逻辑非>按位取反
- 乘除>加减>按位左右移
- 大小比较运算>相等比较运算
- 按位与>按位异或>按位或
- 逻辑与>逻辑或
- 赋值操作
小结
- 逻辑运算中有特殊的短路法则,结果确定后不再向下计算
- C语言中的真值对应非零值,假值对应零值
- 位运算直接对数据的二进制位进行操作
- 位运算的操作数只能是整型数(浮点数不能直接进行位运算)
五、深度剖析位运算
不同类型的本质在于:
占用的内存大小不同,如:short占用2字节,int占用4字节
表示具体数据的方式不同
- 正整数用原码表示,负整数用补码表示
- 整数型和浮点型的二进制表示不同
位运算时需要明确的知道的事
- 操作数的类型(占用的内存大小)
- 操作数是正数还是负数(符号位,数据表示)
- 不同类型的操作数先自动对齐再进行位运算(补符号位)
如下面的一段代码:
short a = 1; int b = 4; int c = a | b; printf("c = %d\n",c);
b为int类型,占4个字节,a为short类型,占2个字节。所以a要先要补符号位,由于a是正数,所以补0,这样就可以进行位运算了,得出c的结果为5。
下面来看一段代码:
#include <stdio.h> int main() { short a = 1; short b = 2; int c = a - b; c = c >> 4; printf("c = %d\n", c); c = c * -1 * 16 >> 4; printf("c = %d\n", c); printf("c = %d\n", 16 << 2); return 0; }
下面为输出结果:
小结论
- 正数符号位为0,右移运算时,高位补0,低位移除
- 负数符号位为1,右移运算时,高位补1,低位移除
- 左移运算时,最高位移除,低位补0
- 最高位的具体位置,由数据类型决定
类型补充小知识
- char 字符型,一个字节的整型,范围[-128,127]
- 字符数据(单引号括起来的字符)的本质是整型数
- char类型的变量可以打印为整数或者字符
再看一段代码:
#include <stdio.h> int main() { char c = 'A'; short a = c; int b = c; printf("c = %c\n", c); printf("c = %d\n", c); printf("a = %d\n", a); printf("b = %d\n", b); c = 0x40; printf("c = %x\n", c); printf("c = %d\n", c); c = c << 1; printf("c = %d\n", c); c = c << 1; printf("c = %d\n", c); return 0; }
下面为输出结果:
需要注意的是,因为c为char类型,所以64左移1位后,用二进制表示为1000 0000,最高位的1表示符号位,所以就是-128。
小结
- 不同类型的本质区别是:占用内存不同,数据表示不同
- 右移运算时,高位补符号位,低位移除
- char是只占用一个字节的整型,可表示英文字符
- 数据符号位的具体位置由数据类型决定
到此这篇关于C语言中各种运算类型全面总结的文章就介绍到这了,更多相关C语言运算类型内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!