当前位置: 首页 > web >正文

3级-运算符

前情回顾:在2级的时候,我们学习的有:占位符、输出函数、输入变量......


 

概念

什么是运算符?

算术运算符

关系运算符

自增和自减运算符

逻辑运算符

赋值运算符

位运算符

运算符的优先级


 

概念

什么是运算符?

答:运算符是用来对数据进行各种运算的符号,用于执行数学计算、逻辑判断、位操作等操作。在C语言中,运算符分为:算术运算符、关系运算符、逻辑运算符、赋值运算符、位运算符。


算术运算符

加法(+):用于两数相加。例如 int a = 4+ 5;,结果 a 的值为 9

减法(-):用于两数相减。例如 int a = 5 - 4;,结果 a 的值为 1

乘法(*):用于两数相乘。例如 int a = 4 * 5;,结果 a 的值为 20

除法(/):用于两数相除,结果为商。例如 int a = 6 / 4;,结果 a 的值为 1

取余(%):也叫模运算,用于两数相除,结果为余数。例如 int a = 6 % 4;,结果 a 的值为 2

注意:

除法/的运算结果和运算对象的数据类型有关

假设两个数都是int,则商就是int

例如:16/5->3     6/4->1

假设其中一个或两个都是浮点型数据,则商就是浮点型

例如:16/5.0->3.20000        6.0/4->1.50000

取余%只能对整数,结果是余数,余数的符号与除数相同。

例如:13%3->1        13%-3->1        -13%3->-1        6%4->2        6%-4->2        -6%4->2

程序代码:

#include <stdio.h> int main()	
{printf("16/5=%d\n",16/5);printf("16/5.0=%lf\n",16/5.0);printf("13%%3=%d\n",13%3);    //如果想输出%这个字符,需要使用%%printf("13%%-3=%d\n",13%-3);printf("-13%%3=%d\n",-13%3);return 0;
}

运行结果:


关系运算符

关系运算符常用在条件判断,循环结构。返回的结果只有真或假,而在C语言中,用整型1来表示,由整型0来表示。

小于(<):x<y。用于判断x是否小于y。例如 int a = (4<5);,结果 a 的值为 1(真)

大于(>):x>y。用于判断x是否大于y。例如 int a = (4>5);,结果 a 的值为 0(假)

等于(==):x==y。用于判断x是否等于y。例如 int a = (4==5);,结果 a 的值为 0(假)

不等于(!=):x==y。用于判断x是否不等于y。例如 int a = (4!=5);,结果 a 的值为 1(真)

小于等于(<=):x<=y。用于判断x是否小于或等于y。例如 int a = (4<=5);,结果 a 的值为 1(真)

大于等于(>=):x>=y。用于判断x是否大于或等于y。例如 int a = (4>=5);,结果 a 的值为 0(假)

程序代码:

#include <stdio.h> int main()	
{printf("4<5=%d\n",4<5);printf("4>5=%d\n",4>5);printf("(4==5)=%d\n",4==5);printf("(4!=5)=%d\n",4!=5);printf("4<=5=%d\n",4<=5);printf("4>=5=%d\n",4>=5);return 0;
}

结果:


自增和自减运算符

前自增(++a):先将a的值加 1,再使用。int a=1,b;  int b = ++a; 结果 b 的值为 2 ;a的值为2

后自增(a++):先使用 a 的值,再将其加 1。int a=1,b;  int b = a++; 结果 b 的值为 1 ;a的值为2

前自减(--a):先将a的值减 1,再使用。int a=1,b;  int b = --a; 结果 b 的值为 0 ;a的值为0

后自减(a--):先使用 a 的值,再将其减 1。int a=1,b;  int b = a--; 结果 b 的值为 1 ;a的值为0

自增或自减最终a的值都会+1或-1。唯一区别是前置和后置。

技巧:看a的位置。

如b=a++,a最靠近b,所以b=a,然后a=a+1。

再如前置b=++a,a离b最远,所以a=a+1,然后b=a。

#include <stdio.h> int main()	
{int a1 = 1;int b1 = ++a1;    //前自增printf("a1=%d,b1=%d\n",a1,b1);int a2 = 1;int b2 = a2++;    //后自增printf("a2=%d,b2=%d\n",a2,b2);return 0;
}

结果: 


逻辑运算符

(!):对操作数取反,!假变真,!真变假。例如:int a = !(4>5),虽然4>5为假,但经过非变真。所以结果 a 的值为 1(真)

逻辑与(&&):只有当两个操作数都为真时,结果才为真。0&&1= 0、1&&0 = 0、0&&0=0、1&&1=1。例如:int a = (4>5) && (2<3),结果 a 的值为0(假) 原因:4>5=0,2<3=1,而0&&1= 0

小知识:a++和a--也可以使用到逻辑运算中(除了1表示真,还有大于0的数也表示真)

程序代码:

#include <stdio.h> int main()	
{int a1 = 1;int b1 =  (4>5) && (a1++);	//0,因为4>5假,不执行a1++printf("b1=%d,a1=%d\n",b1,a1);int a2 = 1;int b2 =  (4<5) && (a2++);	//1,1&&a1=1(真)。因为a2++是前自增,是先使用a2值,而不是a2++后的值,并且会执行a2++printf("b2=%d,a2=%d\n",b2,a2);return 0;
}

这里值得注意的是:假如&&运算时,检测到左边为假,则不会检测右边,结果直接为假!

例如:

int a1=1;

int b1 = (4>5) && (a1++);

在这里&&运算检测到4>5为假,不会再执行a1++这一操作,所以a1自增失败,值还是1

口诀:逻辑与,左假,右不执行

结果:

逻辑或(||):当一个或两个操作数都为真时,结果就为真。0||1= 1、1||0 = 1、0||0=0、1||1=1。例如:int a = (4>5) || (2<3),结果 a 的值为1(真) 原因:4>5=0,2<3=1,而0||1= 1。

这里值得注意的是:假如||运算时,检测到左边为真,则不会检测右边,结果直接为真!

例如:

int a1=0;

int b1 = (2<3) || (a1++);

在这里||运算检测到2<3为真,不会再执行a1++这一操作,所以a1自增失败,值还是0。

口诀:逻辑或,左真,右不执行

#include <stdio.h> int main()	
{int a1 = 0;int b1 =  (2<3) || (a1++);	//1, 1||a1=1(真),不执行a1++printf("b1=%d,a1=%d\n",b1,a1);int a2 = 0;int b2 =  (2>3) || (a2++);	//0, 0||a2=1(真),然后执行a2++printf("b2=%d,a2=%d\n",b2,a2);return 0;
}

结果:


赋值运算符

在有些时候,我们需要改变变量的值,希望它变成2倍、3倍或者减少一半等等,我们可以用一种赋值运算符进行数字运算后的赋值。例如:

int a = 2; 将2赋值给int类型变量a,结果 a 的值为2

a += 3; 等价于 a = a+3,结果 a 的值为 2+3=5

a *= 2; 等价于 a = a*2,结果 a 的值为 5*2=10

a /= 2; 等价于 a = a/2,结果 a 的值为 10/2=5

a -= 3; 等价于 a = a-3;,结果 a 的值为 5-3=2


位运算符

位运算符常用于二进制数的处理,像是在单片机编程中常会用到。首先我们需要先了解进制转换、编码形式。相关知识,可以去1级重新回顾一下。

除此之外,还需要了解与、或和异或。

与:0&0=0、1&0=0、0&1=0、1&1=1

口诀:与运算,遇0变0,遇1不变

或:0|0=0、1|0=1、0|1=1、1&1=1

口诀:或运算,遇0不变,遇1变1

异或:0^0=0、1^0=1、0^1=1、1^1=0

口诀:异或运算,相同为0,不同为1

按位与(&):将两个数转为二进制,对应位都进行与运算,都为 1 时结果为 1,否则为 0。

例如:

(1)int a= 5;  5转二进制为0101,因为int是32位的,将其正数扩充为32位:0000 0000 0000 0000 0000 0000 0000 0101

(2)int b= 9; 9转二进制为1001,因为int是32位的,将其正数扩充为32位:0000 0000 0000 0000 0000 0000 0000 1001

(3)进行 a & b。a和b每一位对应与运算,根据口诀,前面不变,与运算的只有0101&1001,结果得0001,最终结果为0000 0000 0000 0000 0000 0000 0000 0001

#include <stdio.h> int main()	
{int a=5,b=9;printf("5&9=%d",a&b);return 0;
}

结果: 

按位或(|):将两个数转为二进制,对应位都进行或运算,都为 0 时结果为 0,否则为 1。

例如:

(1)int a= 5;  5转二进制为0101,因为int是32位的,将其正数扩充为32位:0000 0000 0000 0000 0000 0000 0000 0101

(2)int b= 9; 9转二进制为1001,因为int是32位的,将其正数扩充为32位:0000 0000 0000 0000 0000 0000 0000 1001

(3)进行 a | b,a和b每一位对应或运算,根据口诀,前面不变,或运算的只有0101|1001,结果得1101。最终结果为0000 0000 0000 0000 0000 0000 0000 1101

#include <stdio.h> int main()	
{int a=5,b=9;printf("5|9=%d",a|b);return 0;
}

结果: 

按位异或(^):将两个数转为二进制,对应位都进行异或运算,相同为 0,不同为 1。

例如:

(1)int a= 5;  5转二进制为0101,因为int是32位的,将其正数扩充为32位:0000 0000 0000 0000 0000 0000 0000 0101

(2)int b= 9; 9转二进制为1001,因为int是32位的,将其正数扩充为32位:0000 0000 0000 0000 0000 0000 0000 1001

(3)进行 a ^ b,a和b每一位对应异或运算,根据口诀,前面不变。异或运算的只有0101^1001,结果得1100。最终结果为0000 0000 0000 0000 0000 0000 0000 1100

#include <stdio.h> int main()	
{int a=5,b=9;printf("5^9=%d",a^b);return 0;
}

结果: 

按位取反(~):将操作数转为二进制,对应位都进行取反,0变1,1变0。

例如:

(1)int a= 5;  5转二进制为0101,因为int是32位的,将其正数扩充为32位:0000 0000 0000 0000 0000 0000 0000 0101

(2)进行~a,按位取反(0变1,1变0),结果为1111 1111 1111 1111 1111 1111 1111 1010。因为int类型数据采用补码形式,所以将其转成原码形式:1000 0000 0000 0000 0000 0000 0000 0110

最高符号位为1,转十进制:-6

#include <stdio.h> int main()	
{int a=5;printf("~a=%d",~a);return 0;
}

结果: 

左移运算符(<<):将操作数转为二进制,不管有无符号数都是整体左移n位(<<1左移1位,<<2左移2位...),并且低位补0

例如:

(1)int a= 5;  5转二进制为0101,因为int是32位的,将其正数扩充为32位:0000 0000 0000 0000 0000 0000 0000 0101

(2)进行a<<1,也就是二进制数左移动,并且低位补0,也就是0000 0000 0000 0000 0000 0000 0000 1010

#include <stdio.h> int main()	
{int a=5;printf("a<<1=%d",a<<1);return 0;
}

结果: 

右移运算符(>>):将操作数转为二进制,有符号数的符号位不动,整体右移,正数高位补0,负数高位补1;无符号数整体右移,高位补0。

例如:0101

(1)int a=-5;  a转补码形式为1,1011,因为int是32位的,需要扩充为32位:1111 1111 1111 1111 1111 1111 1111 1011。(原码转补码:除符号位其他位取反,再加1)

(2)进行a>>1,除符号位,剩余位右移,高位补1(补码右移,正数补0,负数补1)。右移结果:1111 1111 1111 1111 1111 1111 1111 1101 接着转成原码形式:1000 0000 0000 0000 0000 0000 0000 0011  (补码转原码--除符号位其他位取反,再加1),转换成十进制就是 -3

#include <stdio.h> int main()	
{int a=-5;printf("a>>1=%d",a>>1);return 0; 
}

结果: 

运算符的优先级

以下是运算符共同使用的情况下的优先级,优先级越高越先执行,但是也不需要刻意背下来,常用就会熟悉。


        在该系列中,文章的前部分采用简短的白话文讲解用法,而后部分采用更深入的角度讲解原理。思考是人类的结晶~如果你觉得有用,给我个点赞、收藏+关注哦~持续更新 

http://www.xdnf.cn/news/6016.html

相关文章:

  • 从数据中台到数据飞轮:实现数据驱动的升级之路
  • 论文学习_Trex: Learning Execution Semantics from Micro-Traces for Binary Similarity
  • SparkSQL入门指南:从基础到实践的全面解析
  • 配置Nginx启用Https
  • 豌豆 760 收录泛滥现象深度解析与应对策略
  • FedTracker:为联邦学习模型提供所有权验证和可追溯性
  • Unity3D 序列化机制:引擎内的应用场景和基本原理
  • vue3项目创建-配置-elementPlus导入-路由自动导入
  • 江苏发改委回复:分时电价调整对储能项目的影响 源网荷储一体化能量管理系统储能EMS
  • 为什么企业建站或独立站选用WordPress
  • C程序的存储空间分配
  • 汉得 x 真味生物|H-ZERO PaaS项目启动,共启数字化新征程!
  • 可视化+智能补全:用Database Tool重塑数据库工作流
  • java 结合 FreeMarker 和 Docx4j 来生成包含图片的 docx 文件
  • 七、深入 Hive DDL:管理表、分区与洞察元数据
  • 邀请函|PostgreSQL培训认证报名正式开启
  • 演员评论家算法
  • LS-DYNA一箭穿心仿真分析
  • Oracle CDB 与 Non-CDB (NoCDB) 的区别
  • Linux(1)编译链接和gcc
  • typedef unsigned short uint16_t; typedef unsigned int uint32_t;
  • Lin4neuro 系统详解
  • Qt应用程序启动时的一些思路:从单实例到性能优化的处理方案
  • zabbix最新版本7.2超级详细安装部署(一)
  • VS Code怎么设置python SDK路径
  • 理解计算机系统_并发编程(5)_基于线程的并发(二):线程api和基于线程的并发服务器
  • Ascend的aclgraph(六)AclConcreteGraph
  • 技术并不能产生一个好的产品
  • solidwors插件 开发————仙盟创梦IDE
  • # YOLOv3:基于 PyTorch 的目标检测模型实现