操作符(运算符)详解

简介: 🐰算数操作符:+ - * / %🐰移位操作符:<< >>🌸进制的定义 🌸整数二进制表示形式🌸<< 左移操作符🌸>>右移操作符🐰位操作符:& | ^ 🌸&(按位与)|(按位或) 🌸^(按位异或)🐰赋值操作符: =

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

🐰算数操作符:+    -    *    /    %

🐰移位操作符:<<    >>

🌸进制的定义

🌸整数二进制表示形式

🌸<< 左移操作符

🌸>>右移操作符

🐰位操作符:&   |   ^  

🌸&(按位与)|(按位或)

🌸^(按位异或)

🐰赋值操作符:    =

🐰复合赋值符:+=    -=    *=    /=    %=    <<=    >>=    &=    !=    ^=

🐰单目操作符:!    -    +    &    *    ~    --    ++

🐰关系操作符:>    >=    <    <=    !=    ==

🐰逻辑操作符:&&      ||

🐰条件操作符:exp1?exp2:exp3(三目操作符)

🐰逗号表达式:exp1,exp2,exp3,…,expN

🐰下标引用操作符 [ ]

🐰函数调用操作符 ( )

🐰结构成员访问操作符

🐰运算符的优先级顺序表

🐰隐式类型的转换-整形提升


🐰算数操作符:+    -    *    /    %

/:除法——得到的是商。

除法操作符的两个的操作数都是整数的话,执行的是整数除法。

除法操作符的两个的操作数只要一个是浮点数,执行的是小数数除法。

例如:

1. 9/2        就是整数除法
2. 9/2.0或者9.0/2.0        就是小数除法

%:取模(取余)——得到的是余数

‼️注:取模操作符的两个个操作数必须为整数

🐰移位操作符:<<    >>

移位操作符(移动的是二进制的位)<<:左移操作符    >>:右移操作符

🌸进制的定义

10进制的数据中:都是0~9的数字组成

2进制的数据:0~1的数字组成

8进制的数据:0~7的数字组成

16进制的每一位:0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f

(2进制,8进制,10进制,16进制只不过是数值的表达形式而已)

例如:数值10

1010    2进制

12        8进制

10        10进制

a           16进制

🌸整数二进制表示形式

整数的二进制表示形式有三种:原码、反码、补码,正数的原、反、补码是相同的,只有负数的原、反、补码需要转换。

转换规则

原码:把一个数按照正负直接翻译成二进制就是原码

反码:原码的符号位不变,其他位按位取反

补码:反码+1

‼️ 注:原、反、补码的最高位是符号位

1. 例如:5 -5是整数,一个整形变量是4字节32比特位
2. 5
3. 原码:00000000000000000000000000000101
4. 反码:00000000000000000000000000000101
5. 补码:00000000000000000000000000000101
6. -5
7. 原码:10000000000000000000000000000101
8. 反码:11111111111111111111111111111010
9. 补码:11111111111111111111111111111011

‼️注:整数在内存中存储的是补码

🌸<< 左移操作符

<<左移操作符:左边抛弃,右边补0

例如:

1. int a=3;
2. int b=a<<1;
3. a:00000000000000000000000000000011(补码)
4. a<<1:00000000000000000000000000000110
5. b:00000000000000000000000000000110
6. int a=-3
7. int b=a<<1;
8. a:
9. 原码:10000000000000000000000000000011
10. 反码:111111111111111111111111111111111111111100
11. 补码:111111111111111111111111111111111111111101
12. 原码到补码:取反,+1(符号位不变)
13. 补码到原码:-1,取反(符号位不变)和取反,+1(符号位不变)
14. a:111111111111111111111111111111111111111101
15. a<<1:111111111111111111111111111111111111111010
16. b:111111111111111111111111111111111111111010

🌸>>右移操作符

1:>>算术右移(左边用原来的符号位填充,右边丢弃

2:   >>逻辑右移(左边直接用0填充,右边丢弃

右移的时候,到底采用的是算术右移?还是逻辑右移,是取决于编译器的(常见的是算术右移

‼️注:对于移位操作符,不要移动负数位,这个是标准未定义的

例:

Int a=10;

a<<-1(错误)

🐰位操作符:&   |   ^  

位操作符:&(按位与)    |(按位或)   ^(按位异或)  

‼️注:位是二进制位,操作数必须是整数

🌸&(按位与)|(按位或)

&:相同为相同的数,相异为0

int a=3 b=-5 ;

1. a:00000000000000000000000000000011    3的补码
2. b:10000000000000000000000000000101    
3.   11111111111111111111111111111010 
4.   11111111111111111111111111111011    -5的补码
5. a&b:00000000000000000000000000000011

|: 相同为相同的数,相异为1

1. a|b:11111111111111111111111111111011 
2. a^b:11111111111111111111111111111000

🌸^(按位异或)

异或:相同为0,相异为1

规则(异或支持交换律的)

a^a=0

0^a=a

a^a^b=b

a^b^a=b

例题

交换a和b的值,不能用第三个变量

1. #include<stdio.h>
2. int main()
3. {
4.     int a=3;
5.     int b=5;
6.     a=a^b;//000000000011^000000000101=000000000110(6)
7.     b=a^b;//000000000110^000000000101=00000000011(3)
8.     //b=a^b^b=a
9.     a=a^b;//000000000110^00000000011=00000000101(5)
10.     //a=a^b^a
11.     return 0;
12. }

🐰赋值操作符:    =

a=b=c+1;//连续赋值(可读性较低)

🐰复合赋值符:+=    -=    *=    /=    %=    <<=    >>=    &=    !=    ^=

🐰单目操作符:!    -    +    &    *    ~    --    ++

~:按位取反(二进制)

例:

1. int a=0
2. a:00000000000000000000000000000000
3. ~a:11111111111111111111111111111111 补码
4.    11111111111111111111111111111110 反码
5.    10000000000000000000000000000001 原码
6. ~a=-1

‼️注:While(~scanf(“%d”,&a)),scanf读取失败会返回EOF,就是-1,-1按位取反则是0

--:前置:先使用,再--,后置:先使用,再--

++:前置:先使用,再++,后置:先使用,再++

1. int a=10,b=0;
2.     //b=a++;//后置++:先使用,再++,先把a=10值赋给b,然后a再++,a=11,b=10;
3.     //b=++a;//前置++:先++,再使用,a先++,a=11,然后把a=11赋值给b,b=11;
4.     b=a--;
5.     b=--a;

🐰关系操作符:>    >=    <    <=    !=    ==

‼️注:=(赋值操作符)和==(关系操作符)

🐰逻辑操作符:&&      ||

逻辑操作符关注真假(1和0),&&(逻辑与)和||(逻辑或)

例:

1. int i=0,a=0,b=2,c=3,d=4;
2.    i=a++&&++b&&d++;//如果左边为假,后面就不需要算了
3. printf("a=%d b=%d c=%d d=%d i=%d\n",a,b,c,d,i);
4. 结果为:a=1 b=2 c=3 d=4 i=0,因为a++,是后置++,所以此时a值为0,则后后面的不需要计算,就为初始值
5.    i=a++||++b||d++;//如果左边为真,后面就不需要算了
6.   printf("a=%d b=%d c=%d d=%d i=%d\n",a,b,c,d,i);
7. 结果为:a=1 b=3 c=3 d=4 i=0,因为++b前置++,此时b值不为0,所以后面的d不会进行计算。

🐰条件操作符:exp1?exp2:exp3(三目操作符)

1. int a=5,b=3,c=0;
2. 
3. c=a>b?a:b

🐰逗号表达式:exp1,exp2,exp3,…,expN

1. 例如两数中求最大值
2. #include<stdio.h>
3. int main()
4. {
5. int a=3,b=5;
6. int max=a>b?a:b
7. return 0;
8. }

🐰下标引用操作符 [ ]

数组里常用,arr[ ],arr[ i ]...

🐰函数调用操作符 ( )

1. Int len=strlen(“abc”);
2. 
3. Int Add(3,5)//3,5就是( )的操作数

🐰结构成员访问操作符

(1).    结构体变量.结构体成员名

(2)->    结构体指针->结构体成员

1. struct  S
2. 
3. {
4. 
5.     int num;
6. 
7.     char c;
8. 
9. };
10. 
11. void test(struct S* ps )
12. 
13. {
14. 
15.     printf(“%d”,(*ps).num);
16. 
17.     printf(“%c”,(*ps).c)
18. 
19.     printf(“%d”,ps->num);//只有结构体指针才能使用->
20. 
21.     printf(“%c”,ps->.c)
22. 
23. }
24. 
25. int main()
26. 
27. {
28. 
29. struct S s={100,’b’};
30. 
31. printf(“%d\n”,s.num);
32. 
33. printf(“%c\n”,s.c);
34. 
35. test(&s)
36. 
37. return 0;
38. 
39. }

🐰运算符的优先级顺序表

优先级

操作符(运算符)

名称

使用原型

结合规律

注释

  • 1

[ ]

数组下标 

数组名[常量表达式] 

从左到右 

( )

小括号 

(表达式)/(强制转换类型) 

.

成员选择(对象) 

对象.成员名 

->

成员选择(指针) 

指针->成员名 

  • 2

!

逻辑反操作符(逻辑非) 

!表达式 

从右到左 

单目运算符 

-

负值 

-表达式 

+

正值 

+表达式 

&

取地址运算符 

&变量名 

*

间接访问操作符(解引用操作符) 

*指针变量 

~

按位取反操作符 

~表达式 

--

自减运算符 

--变量名/变量名-- 

++

自加运算符 

++变量名/变量名++ 

sizeof

长度运算符 

sizeof(表达式) 

(类型)

强制类型转换 

(数据类型)表达式 

  • 3

/

除 

表达式/表达式 

从左到右 

双目运算符 

*

乘 

表达式*表达式 

%

取模(取余) 

整形表达式%整形表达式 

  • 4

+

加 

表达式+表达式 

-

减 

表达式-表达式 

  • 5

<<

左移 

变量<<表达式 

>>

右移 

变量>>表达式 

  • 6

>

大于 

表达式>表达式 

从左到右 

双目运算符 

>=

大于等于 

表达式>=表达式 

<

小于 

表达式<表达式 

<=

小于等于 

表达式<=表达式 

  • 7

==

等于 

表达式==表达式 

!=

不等于 

表达式!=表达式 

  • 8

&

按位与 

表达式&表达式 

从左到右 

双目运算符 

  • 9

^

按位异或 

表达式^表达式 

  • 10

|

按位或 

表达式|表达式 

  • 11

&&

逻辑与 

表达式&&表达式 

  • 12

||

逻辑或 

表达式||表达式 

  • 13

?:

条件运算符 

表达式1?表达式2:表达式3 

从右到左 

三目运算符 

  • 14

=

赋值运算符 

变量=表达式 

从右到左 

/=

除后赋值 

变量/=表达式 

*=

乘后赋值 

变量*=表达式 

%=

取模后赋值 

变量%=表达式 

+=

加后赋值 

变量+=表达式 

-=

减后赋值 

变量-=表达式 

<<=

左移后赋值 

变量<<=表达式 

>>=

右移后赋值 

变量>>=表达式 

&=

按位与后赋值 

变量&=表达式 

^=

按位异或后赋值 

变量^=表达式 

|=

按位或后赋值 

变量!+表达式 

  • 15

,

逗号运算符 

表达式,表达式... 

从左到右 

‼️注:同一优先级的运算符,顺序由结合规律所决定

🐰隐式类型的转换-整形提升

整形提升是按照变量的数据类型的符号来提升的

(1)负数的整形提升

char c1=-1;

变量c1的二进制位(补码)中只有8个bit位;

11111111

因为char为有符号的char

所以整形提升的时候,高位补充符号位,即为1

提升之后的结果是:

111111111111111111111111111111111

(2)正数的整形提升

char c2=1;

变量是c2的二进制(补码)中只有8个bit位;

00000001

因为char为有符号的char

所以整形提升的时候,高位补充符号位,即为0

提升之后的结果是:

00000000000000000000000000000001

(3)无符号整型提升,高位补0

例题:

 

1. int main()
2. {
3. char a=3;
4. //00000000000000000000000000000011-都是补码
5. //000000111-截断
6. 
7. char b=127;
8. //00000000000000000000000001111111
9. //01111111-截断
10. 
11. char c=a+b;
12. //00000000000000000000000000000011
13. //00000000000000000000000001111111
14. //00000000000000000000000010000010
15. //运算时整形提升
16. //10000010
17. //赋值给c时又发生截断
18. printf("%d\n",c);
19. //10000010
20. //11111111111111111111111110000010-补码
21. //11111111111111111111111110000001-反码
22. //10000000000000000000000001111110-原码
23. //所以打印出的值为10000000000000000000000001111110(二进制),-126(十进制)
24. //%d打印整型提升
25. return 0;
26. }

🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸  



相关文章
|
Web App开发 编解码 监控
防御性设计和开发
“防御性编程(Defensive programming)是防御式设计的一种具体体现,它是为了保证,对程序的不可预见的使用,不会造成程序功能上的损坏。它可以被看作是为了减少或消除墨菲定律效力的想法。”
1205 0
防御性设计和开发
|
SQL 算法 数据库
OceanBase 查询优化 | 学习笔记
快速学习 OceanBase 查询优化
OceanBase 查询优化 | 学习笔记
|
5月前
|
Ubuntu API
在Ubuntu上利用SANE API实现跨平台扫描功能的指南
跨平台扫描功能的实现,在Ubuntu上表演起来,只需要SANE这个神奇魔杖,加上一系列施法步骤,每个命令都像是进行咒语施法,只需轻松点击按键,即可驱动扫描仪进行各种跃动。别忘了,这只是开始,在扫描的舞台上,还有许多舞步等待你去开发和探索。
210 14
|
存储 编解码 边缘计算
从RTMPS到MPEG-DASH:直播带货背后的秘密流程
大家好,我是小米,今天聊聊“社区直播带货”的技术流程。文章介绍了RTMPS协议的安全可靠传输,MPEG-DASH的自适应比特率流媒体技术,以及直播数据如何通过边缘节点和数据中心进行高效处理与分发,确保用户流畅观看。通过这些技术,直播带货不仅画质清晰,还保障了安全性和用户体验。希望本文能帮助你深入了解这一流程。如果有任何问题,欢迎留言讨论!
220 2
|
JavaScript
JS实现简单的打地鼠小游戏源码
这是一款基于JS实现简单的打地鼠小游戏源码。画面中的九宫格中随机出现一个地鼠,玩家移动并点击鼠标控制画面中的锤子打地鼠。打中地鼠会出现卡通爆破效果。同时左上角统计打地鼠获得的分数
327 1
|
5月前
|
NoSQL MongoDB 开发者
Python与MongoDB的亲密接触:从入门到实战的代码指南
本文详细介绍了Python与MongoDB结合使用的实战技巧,涵盖环境搭建、连接管理、CRUD操作、高级查询、索引优化、事务处理及性能调优等内容。通过15个代码片段,从基础到进阶逐步解析,帮助开发者掌握这对黄金组合的核心技能。内容包括文档结构设计、批量操作优化、聚合管道应用等实用场景,适合希望高效处理非结构化数据的开发者学习参考。
301 0
|
8月前
|
SQL 人工智能 BI
《解锁AI与SQL Server的高效协作,提升并发查询能力》
在数字化转型中,企业业务激增使SQL Server面临并发查询的严峻挑战。传统优化手段难以应对复杂场景,而AI技术通过深度数据分析、智能执行计划调整和动态资源分配,精准解决性能瓶颈。案例表明,AI可大幅提升系统响应速度与吞吐量,助力企业在高并发场景下实现高效稳定运行,为未来业务增长提供坚实保障。
186 5
|
10月前
|
JSON 数据挖掘 开发者
1688 商品评论接口系列(1688API)
1688商品评论接口助力电商数据分析与优化。通过该接口,开发者可获取指定商品的评论数据(如昵称、内容、评分等),支持情感分析和质量反馈收集。接口采用HTTP GET/POST请求,返回JSON格式数据。Python示例代码展示如何调用接口并处理响应。应用场景包括商家产品优化、客户服务提升、市场调研及电商平台数据分析。
376 7
|
10月前
|
人工智能 自然语言处理 数据挖掘
《深度解析:VAEs如何重塑数据生成与重建格局》
变分自编码器(VAEs)是人工智能领域中强大的生成模型,广泛应用于图像生成、语音合成及医疗数据分析。其核心由编码器和解码器组成,通过将数据映射到低维潜在空间并重建,实现高效的数据生成与重建。VAEs的潜在空间具有连续性,并引入概率分布以支持创新生成。损失函数引导编码与解码优化,确保高质量的重建效果。VAEs在图像、医疗和自然语言处理等领域展现出巨大潜力,为各行业带来新的发展机遇。
303 18
软件工程师,如何有效缓解工作压力
在这个快速迭代、技术日新月异的数字时代,软件工程师们常常站在技术创新的最前沿。他们肩负着构建高效、可靠软件系统的重任,同时也面临着紧迫的截止日期、复杂的技术难题和持续的学习需求,这些因素共同构成了巨大的工作压力。如何在高压环境下保持冷静、高效与创新,同时维持良好的身心健康,成为了每位软件工程师必须面对的课题,也成为了这一行业亟待解决的问题。
432 57