C语言_干翻操作符_含义+结合性+优先级+例子分析
操作符知识比较杂乱,这里我按照优先级从高向低的顺序进行整理,优先度越高运算中约先进行
由于本人能力有限,有一些遗漏或者错误还希望大家斧正
文章目录
优先度4级(+,-(减))
优先度5级(<<,>>)
优先度6级(<,>,>=,<=,)
优先度7级(==,!=)
优先度8级(&(按位与),|,^)
优先度9级(&&,| |)
优先度10级(?:)
优先级11级(=,+=,-=,*=,/=,%=,>>=,<<=,&=,^=,|=)
优先级12级(,(逗号表达式))
优先度4级(+,-(减))
1.+操作符
含义:运算(不在赘述)
2.-操作符
含义:减法运算符
(注意与负号运算符区分即可不再赘述)
二者的结合性:从左向右。
优先度5级(<<,>>)
1,<<操作符
含义:左移操作符(移动的是储存在内存中二进制的补码)
规则:左边丢弃,右边补零。
#include <stdio.h>
int main()
{
int a = -1;
a = a << 1;
printf("%d",a);
return 0;
}
分析:
-----------------------------------------------------------------
首先我们要知道
整数在计算机中存的是它的补码
原码——>反码——>补码
三者的运算规则为
原码按位取反(符号位不变)——>反码。
反码+1——>补码。
在32位计算机中首位是符号位
表示正负不表示大小。
首位为1表示负数,首位为0表示正数。
eg(都是32位)
10000000000000000000000000000001表示-1
00000000000000000000000000000001表示1
对于正整数规定,它的原码,反码,补码都相同可以直接用。
对于负数计算机存的补码不等,要转成原码才可以直到其大小。
eg:
1 1 1 1 1…1 1(32位)(符号位1说明是负数)补码
1 1 1 1 1…1 0(32位)(补码-1到反码)
1 0 0 0 0…0 1(32位)(符号位不变其余位按位取反到原码)
原码首位为1说明是负数,发现值数字-1。
-----------------------------------------------------------------
a的二进制值在内存中为32个1
移动后
补码变成1 1 1 1 1 …0(32位)
反码 1 1 1 1 1…01(32位)
原码 1 0 0 0 0…10(32位)
翻译原码是-2
结合性:从左向右。
2.>>操作符
含义:右移操作符
有两种移动方式
1,算数右移
2,逻辑右移
算数右移:右边丢弃,左边补充符号位。
逻辑右移:右边丢弃,左边补充0。
vs2019使用的是算数右移
注意不要移动负数位
eg:
a=a>>-1(这种写法编译器不支持)
结合性:从左到右。
优先度6级(<,>,>=,<=,)
用于比较两个数字的关系(这里不再赘述)
结合性:从左到右
优先度7级(==,!=)
1.==操作符
含义:判断两个值是否相同
注意(在C语言中一个等号是赋值,两个等号是判断是否相同。)
==判断是否相同时不能判断字符串与字符串相同
判断字符串相同用的是strcmp函数
结合性:从左向右
2,!=不等于操作符
结合性:从左向右
不在赘述
优先度8级(&(按位与),|,^)
1,&(按位与)操作符
方法:按照二进制位与
#include <stdio.h>
int main()
{
int a = 6;
int b = 4;
int c = a & b;
printf("%d",c);
return 0;
}
注意a,b的二进制位是32位的,这里因为篇幅有限只写出有效部分
&相当于求交集,二进制位1代表真,0代表假
只有同时为真的时候按位的结果才为1,其余情况全部为0
a的二进制位 0 1 1 0
b的二进制位 0 1 0 0
-----------a&b 0 1 0 0
因为是正数,原码=反码=补码
翻译结果为4
结合性:从左到右。
2,| 按位或操作符
方法:
按位或相当与并集,只要二进制位上有1,则最后按位或的结果就为1.
#include <stdio.h>
int main()
{
int a = 6;
int b = 4;
int c = a | b;
printf("%d",c);
return 0;
}
a的二进制位 0 1 1 0
b的二进制位 0 1 0 0
------------a|b 0 1 1 0
发现a|b的结果与a相同为6
结合性:从左到右
3,^ 按位异或操作符
方法:二进制位相同是为0,二进制位不同为1
#include <stdio.h>
int main()
{
int a = 6;
int b = 4;
int c = a ^ b;
printf("%d",c);
return 0;
}
a的二进制位 0 1 1 0
b的二进制位 0 1 0 0
-----------a^b 0 0 1 0
翻译后为2
优先度9级(&&,| |)
1,&& 逻辑与操作符
(注意与&区分,&&不是在二进制上来考虑的,只关心真假)
在C语言中 0为假,非0为真,且计算机输出的真值默认为1.
相当于交集
#include <stdio.h>
int main()
{
int a = 6;
int b = 4;
int c = a &&b;
printf("%d",c);
return 0;
}
注意逻辑与操作可能会出现短路现象)
#include <stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf("a=%d b=%d c=%d d=%d",a,b,c,d);
return 0;
}
分析:
当把a改为1时就会正常
#include <stdio.h>
int main()
{
int i = 0, a = 1, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf("a=%d b=%d c=%d d=%d",a,b,c,d);
return 0;
}
应用:
在 if 语句中使用if(a>1&&a<3)
表示 1<a<3;
结合性:从左到右
2,| | 逻辑或运算符
(同理也要和 | 区分)
相当于并集
#include <stdio.h>
int main()
{
int a = 0;
int b = 3;
printf("%d",a||b);
return 0;
}
同理注意逻辑或也存在短路现象
int main()
{
int i = 0, a = 1, b = 2, c = 3, d = 4;
i = a++||++b || d++;
printf("a=%d b=%d c=%d d=%d i=%d",a,b,c,d,i);
return 0;
}
其原理与逻辑与相同
因为逻辑或前一个表达式为真则一定为真,所以编译器会让++b和d++都不执行,只执行了a++
应用:
用在 if 语句中
if(a>2||a<0)表示a>2或者a<0
结合性:从左向右。
从上面的分析可知&& 与| |都是会控制求值顺序的
优先度10级(?:)
1,?: 条件操作符
三目操作符
格式:
表达式?成立时:不成立时
应用:代替if…else使代码量减少
eg:求三个数最大值
#include <stdio.h>
int main()
{
int a = 0, b = 0, c = 0;
scanf("%d%d%d", &a, &b, &c);
int max = a > b ? a : b;//先比较a,b成立max=a不成立max=b;
int max2 = max > c ? max : c;//在于c比较大于c则max是最大值,否则c是最大值
printf("最大值是%d",max2);
return 0;
}
优先级:从右向左
优先级11级(=,+=,-=,*=,/=,%=,>>=,<<=,&=,^=,|=)
1,=
C语言中=是赋值操作,不在赘述
2,a+=1——a=a+1
其余的类似不在赘述
结合性:从右向左
优先级12级(,(逗号表达式))
1, , 逗号运算符(顺序求值操作符)
含义:用逗号隔开的多个表达式,从左向右依次进行,整个表达式的结果就是最右边表达式的结果。
(括号内的表达式都会计算)
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);
printf("%d",c);
return 0;
}
a=12 c=b=a+1=13应用:使代码简洁
while(a>0) while(a=fun(),a>0)
{ {
表达式1; 可以写成 表达式1;
表达式2; 表达式2;
a=fun(); }
}
结合性:从左到右。