🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀
目录
🐰复合赋值符:+= -= *= /= %= <<= >>= &= != ^=
🐰算数操作符:+ - * / %
/:除法——得到的是商。
除法操作符的两个的操作数都是整数的话,执行的是整数除法。
除法操作符的两个的操作数只要一个是浮点数,执行的是小数数除法。
例如:
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. }
🐰运算符的优先级顺序表
优先级 |
操作符(运算符) |
名称 |
使用原型 |
结合规律 |
注释 |
|
[ ] |
数组下标 |
数组名[常量表达式] |
从左到右 |
|
( ) |
小括号 |
(表达式)/(强制转换类型) |
|||
. |
成员选择(对象) |
对象.成员名 |
|||
-> |
成员选择(指针) |
指针->成员名 |
|||
|
! |
逻辑反操作符(逻辑非) |
!表达式 |
从右到左 |
单目运算符 |
- |
负值 |
-表达式 |
|||
+ |
正值 |
+表达式 |
|||
& |
取地址运算符 |
&变量名 |
|||
* |
间接访问操作符(解引用操作符) |
*指针变量 |
|||
~ |
按位取反操作符 |
~表达式 |
|||
-- |
自减运算符 |
--变量名/变量名-- |
|||
++ |
自加运算符 |
++变量名/变量名++ |
|||
sizeof |
长度运算符 |
sizeof(表达式) |
|||
(类型) |
强制类型转换 |
(数据类型)表达式 |
|||
|
/ |
除 |
表达式/表达式 |
从左到右 |
双目运算符 |
* |
乘 |
表达式*表达式 |
|||
% |
取模(取余) |
整形表达式%整形表达式 |
|||
|
+ |
加 |
表达式+表达式 |
||
- |
减 |
表达式-表达式 |
|||
|
<< |
左移 |
变量<<表达式 |
||
>> |
右移 |
变量>>表达式 |
|||
|
> |
大于 |
表达式>表达式 |
从左到右 |
双目运算符 |
>= |
大于等于 |
表达式>=表达式 |
|||
< |
小于 |
表达式<表达式 |
|||
<= |
小于等于 |
表达式<=表达式 |
|||
|
== |
等于 |
表达式==表达式 |
||
!= |
不等于 |
表达式!=表达式 |
|||
|
& |
按位与 |
表达式&表达式 |
从左到右 |
双目运算符 |
|
^ |
按位异或 |
表达式^表达式 |
||
|
| |
按位或 |
表达式|表达式 |
||
|
&& |
逻辑与 |
表达式&&表达式 |
||
|
|| |
逻辑或 |
表达式||表达式 |
||
|
?: |
条件运算符 |
表达式1?表达式2:表达式3 |
从右到左 |
三目运算符 |
|
= |
赋值运算符 |
变量=表达式 |
从右到左 |
|
/= |
除后赋值 |
变量/=表达式 |
|||
*= |
乘后赋值 |
变量*=表达式 |
|||
%= |
取模后赋值 |
变量%=表达式 |
|||
+= |
加后赋值 |
变量+=表达式 |
|||
-= |
减后赋值 |
变量-=表达式 |
|||
<<= |
左移后赋值 |
变量<<=表达式 |
|||
>>= |
右移后赋值 |
变量>>=表达式 |
|||
&= |
按位与后赋值 |
变量&=表达式 |
|||
^= |
按位异或后赋值 |
变量^=表达式 |
|||
|= |
按位或后赋值 |
变量!+表达式 |
|||
|
, |
逗号运算符 |
表达式,表达式... |
从左到右 |
‼️注:同一优先级的运算符,顺序由结合规律所决定
🐰隐式类型的转换-整形提升
整形提升是按照变量的数据类型的符号来提升的
(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. }
🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸