C语言————操作符详解
C语言中的操作符我们学过很多,这里我就不一一列举了,我来讲解一些我们容易忘记的、不常见的一些操作符。
一、移位操作符
移位操作符的操作数只能是整数;移动的是二进制位补码;
1、左移操作符<<:(有*2的效果)
移动规则:左边抛弃,右边补0。
举例说明:
#include <stdio.h>
int main()
{int a = 6;int b = -6;int A = (a << 1);//A为a左移一位得到的数int B = (b << 1);//B为b左移一位得到的数printf("%d %d", A, B);return 0;
}
注意:上方a的移位是对a的补码进行的操作,移动一位之后,得到的是A的补码,再转换为A的原码。其中原码取反+1——>补码,补码取反+1——>原码。此外,操作数可以是负数,移动的位数不能是负数,不能是移动-1位。
2、<<=:左移复合赋值
a<<=1; //将a左移1位,并赋值给a;
3、右移操作符>>:(有/2的效果)
- 逻辑右移:左边用0填充,右边丢弃。
- 算术右移:左边用原操作数符号位填充,右边丢弃。
用哪种右移的方法,主要取决于编译器的不同,大多数编译器都为逻辑右移。其与左移操作符的用法相似,这里小博就不举例说明了。
4、>>=:右移复合赋值
同样和左移相似,右移也有复合赋值操作。
a>>=1; //将a右移1位,并赋值给a;
二、位操作符
位操作符的操作数必须都是整数;且都是对操作数的二进制补码进行一位一位进行操作。
1、按位与&
这里要区分一下&&逻辑与,不要搞混了。
运算规则:有0则0,同1则1;
2、按位或|
这里要区分一下||逻辑或,不要搞混了。
运算规则:有1则1,同0则0;
3、按位异或^
运算规则:相同为0,相异为1;
典型:a^a=0;0^a=a;
非常巧妙的一道例题,不创建临时变量(第三个变量),实现两个数的交换。
#include <stdio.h>
int main()
{int a = 5;int b = 6;a = a ^ b;b = a ^ b; //代入上面的a,b=a^b^b=a;a = a ^ b; //代入上面的a,b,a=a^b^a=b;printf("a=%d,b=%d", a, b);return 0;
}
牛逼不!!语言的力量就是如此强大!!
当你会了这个操作,就可以在你同学面前秀一波,我们平常用三个碗去实现两个数的交换,如今根本不用借助外物。╰(*°▽°*)╯
如下:求1和-1的&、|、^
补充:原码取反+1——>补码,补码取反+1——>原码
4、按位取反~
同样是对操作数的二进制补码进行按位取反:
int n = 1;
int m = ~n;
n=00000000000000000000000000000001 //1原码=补码11111111111111111111111111111110 //~1的补码
—>10000000000000000000000000000010 //取反,+1,变成~1原码~1==-2
5、应用举例
计算一个数的二进制数中有多少个1:
方法1:
//计算一个数的二进制数中有多少个1
#include <stdio.h>
int main()
{int n;int count = 0;scanf("%d", &n);for (int i = 0; i < 32; i++){if (((n >> i) & 1) == 1)count++;}printf("%d", count);return 0;
}
方法2:
用 n=n&(n-1) 算法求,分析一下:
#include <stdio.h>
int main()
{int n = 0;int count = 0;scanf("%d", &n);while (n){n = n & (n - 1);count++;}printf("%d", count);return 0;
}
上面的两种方法,我们确实很难想到,但是我们都是从不会到会,不要焦虑,多积累就好,看的多了也就熟悉了。
三、逗号表达式
exp1,exp2,exp3,......,expN
从左向右依次计算,整个式子的结果是最后一个表达式的结果:
int a = 1;
int b = 3;
int c = (a / 3, b % a, b / 2);//逗号表达式
if (a = b - 1, b = c - 2, c > 0)
while (a == 1, a + b == 0, c != 0)
无论是赋值,还是判断,都可用逗号表达式。
四、下标访问 [ ] ,函数调用 ()
printf("%d",arr[1]); //这里的打印数组中的元素用到的[]就是一个操作符
没想到吧!我们常用的 [ ] 居然是一个下标访问操作符。其中arr[1]这个整体称作操作数。
int main()
{test(); //调用该函数中的()为操作符
}
函数调用中的()是一个函数调用操作符,其中test称为操作数,注意第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
五、操作符的属性
1、优先级、结合性
如果两个运算符优先级相同,无法判断先计算谁、后计算谁,就可以看结合性。
优先级由高到低排列
该表格不用背,记住下面一些就可以了,理解着记忆:
- (()) //先计算()里面的
- 自增(减)运算符(++,--)
- 单目运算符(+,-)
- *,/
- +,-
- 关系运算符(<、>等等)
- 赋值运算符(=)
C Operator Precedence - cppreference.comhttps://en.cppreference.com/w/c/language/operator_precedence.html好了,小博今天就讲这么多了!欢迎大家留言评论!!😊😊
这里小博送给大家自己喜欢的一句话:旧事不提,但介意的事,会永远介意。
加油!!