目录
一:操作符分类
1:算数操作符
+ - * / %
ps:1:除了%操作符只能作用于整数,其他算术操作符可以作用于整数和浮点数。
2: %操作符的返回值为整除后的余数。
3:对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
4:/:除数不能为零,否则会导致运行时错误。在进行除法操作时,要确保除数不为零。
5:整数除法和取模:在C语言中,当两个整数相除时,结果会被截断为整数部分,而不是四舍五入。例如,5 / 2的结果是2而不是2.5。类似地,取模操作符%返回的是除法的余数。
2:移位操作符
<<左移操作符(将二进制数向左移动)
>>右移操作符(将二进制数向右移动)
ps:1:移位操作符的操作数只能是整数
2:不要移动负数位或者大于等于32位,这是标准未定义行为!(正确取值0-31)
1:左移操作符(<<)
(左边舍弃右边补0)
如:int num=20;
num在内存中的二进制00000000000000000000000000010100
num<<1 的结果: 0 00000000000000000000000000101000 即40
ps:<<1把32位每个位左移1位,相当于给每一位的权值乘2。总体表现乘2;
那么可以推导 <<n,把32位每个位左移n位,相当于给每一位的权值乘2的n次方。总体表现乘2的n次方。
如int mum =20; num<<1==40; num<<2==80;
注意:左移操作符并不会改变原有的值。
若想改变,应将左移后的值赋给自身:
2:右移操作符(>>)
右移运算分两种:
1. 逻辑移位:左边用0填充,右边丢弃
2. 算术移位:左边用原该值的符号位填充,右边丢弃。ps:一般来说正数是采用逻辑位移,负数采用算数位移。但具体的行为仍然取决于编程语言和编译器的实现,不同编译器和语言上会有不同。
正数:
int mum=1;
num在内存中的二进制:00000000000000000000000000000001
num>>1 :00000000000000000000000000000000 1 //即:0 左边用0填充,右边丢弃
int num
负数:
ps:(内存中整数以补码形式存在,正数的原码反码补码相同,负数的补码为原码取反(除了符号位保留,不取反)再加1,-1的补码全为1)
如果是算数位移:
int num=-1;
num在内存中的二进制:11111111111111111111111111111111 1为符号位
num>>1 :11111111111111111111111111111111 1
//即:-1 左边用原该值的符号位填充,右边丢弃。
如果是逻辑位移:
num>>1 :01111111111111111111111111111111 1
//即:一个很大的正数。 左边用0填充,右边丢弃
可以推导:对于右移操作符,如果是算数位移的情况下,num<<n其结果并不是除以2的n次幂,而是除以2的n次幂向下取整,这是因为右移操作会将二进制表示的数值向右移动指定的位数,丢弃被移出的位,并根据移位后的最高位来确定新的值。在算术右移中,符号位会被保留,并用于填充移位后左边空出的位。因此,右移操作相当于将数值除以2并向下取整,而不仅仅是简单地除以2。
例如-1>>1==-1; -3>>1==-2; -4>>1==-2; 5>>1==2
3:位操作符
与(&):对两个操作数的每个对应位执行与操作,结果为1的条件是两个操作数对应位都为1,否则为0。(同1为1,否则为0)
或(|):对两个操作数的每个对应位执行或操作,结果为1的条件是两个操作数对应位至少有一个为1,否则为0。(有1为1否则为0)
非(~):对操作数的每个位执行取反操作,即0变为1,1变为0。
异或(^):对两个操作数的每个对应位执行异或操作,结果为1的条件是两个操作数对应位不相同,否则为0。(相同为0,不同为1)
ps:他们的操作数必须是整数。
举例:
int mum=2,a=5;
num在内存中的2进制:00000000000000000000000000000010
a在内存中的2进制 :00000000000000000000000000000101
num&a :00000000000000000000000000000000
num|a :00000000000000000000000000000111
~a :111111111111111111111111111111111010
num^a :00000000000000000000000000000111
位操作符的应用:
清除最低位的1(n & (n-1)):这个技巧可以用来将一个整数的二进制表示中最低位的1清除为0。这在一些算法中非常有用,比如计算一个整数的二进制表示中有多少个1。
检测奇偶性:使用位操作符可以非常高效地检测一个整数是奇数还是偶数。具体地,可以使用 (n & 1) == 0 来检测n是否为偶数,因为偶数的最低位是0。
交换两个数:可以使用异或操作符来交换两个变量的值,即 a = a ^ b; b = a ^ b; a = a ^ b; 这种技巧可以避免使用临时变量。
位掩码:通过使用位操作符,可以轻松地创建和操作位掩码,用于对特定位进行设置、清除或者切换。
快速乘除:有时候可以使用位操作符来实现快速乘法和除法,尤其是在处理2的幂次方的情况下。
举例
1:计算num二进制中有多少个1
比如num=3;:num:011(32位省略了前29位)
:num-1:010
: num&num-1 :010//将num的最后一个1变为了0;
如此可以写成循环块:
while(num)
{
count++;
num=num&num-1;
}
printf(“%d”,count);
方法二:
#include <stdio.h>
int main()
{
int num = -1;
int i = 0;
int count = 0;//计数
for(i=0; i<32; i++)
{
if( num & (1 << i) )
count++;
}
printf("二进制中1的个数 = %d\n",count);
return 0;
}
2:实现两个数交换:
公理:a^a==0; a^0==a
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a^b;
b = a^b;//相当于a^b^b相当于a^0相当于a
a = a^b;//相当于a^b^a相当于0^b相当于b
printf("a = %d b = %d\n", a, b);
return 0;
}
4:赋值操作符
= += -= %= /= >>= <<= &= |= ^=
这个没什么好讲的,就是对变量进行赋值,对于(+=,%=,-=,/=0等等之类的复合赋值,其实际效果等同于a==a+x,a==a%x,a==a-x,a==a/x
有几点需要注意:
数据类型匹配:确保赋值操作符两边的数据类型匹配,否则可能会导致类型转换或者数据丢失。例如,将一个浮点数赋值给整数类型变量时,可能会丢失小数部分。
赋值顺序:赋值操作符的右侧表达式会在赋值之前进行计算,因此在使用复合赋值操作符时,要注意表达式的计算顺序。
5:单目操作符
! //逻辑反操作
- //负值
+ //正值
& //取地址
sizeof //求操作数的类型长度(以字节为单位)
~ //对一个数的二进制按位取反
-- //前置、后置减减
++ //前置、后置加加
* //间接访问操作符(解引用操作符)
(强制类型转换) //强制类型转换
sizeof:用于获取数据类型或变量的大小(即所占的字节数)
int size = sizeof(int);
printf("int类型的大小为:%d 字节\n", size);int arr[5];
int arrSize = sizeof(arr);
printf("数组arr所占的内存大小为:%d 字节\n", arrSize);
sizeof和strlen的区别
sizeof
操作符用于获取数据类型或变量所占的内存大小(即字节数),它是在编译时求值的。例如,在C语言中,sizeof(int)
返回整型数据类型所占的字节数,而sizeof(arr)
返回数组arr
所占的内存大小。
strlen
函数用于计算字符串的长度,即它返回一个以 null 结尾的字符串中的字符数(不包括 null 终止符)。strlen
是在运行时求值的,因为它需要遍历整个字符串来计算其长度。
sizeof
是一个操作符,用于获取数据类型或变量所占的内存大小,是在编译时求值的。功能是求操作数类型的长度,计算的是变量所占内存空间的大小,单位是字节。strlen
是一个函数,用于计算以 null 结尾的字符串的长度,是在运行时求值的。功能是计算字符串的长度,遇到\0停止计算,单位是个,使用时需要引用头文件。(string.h)
//--和++操作符
#include<stdio.h>
int main()
{
int a = 20;
int b = a++;
//该表达式相当于b = a; a = a + 1;
//++前置时是先加加后赋值
//++后置时是先赋值后加加
int c = --b;
//该表达式相当于b = b - 1; c = b;
//--前置时是先减减后赋值
//--后置时是先赋值后减减
printf("%d\n", b);//打印结果为19
printf("%d\n", c);//打印结果为19
return 0;
}
6:关系操作符
>大于
>=大于等于
<小于
<=小于等于
!= 不相等
== 相等
这些也比较简单,没什么讲的,要注意==和=写错导致的错误。
7:逻辑操作符
&& 逻辑与
|| 逻辑或
8:条件操作符
exp1 ? exp2 : exp3//exp1为真,则结果为exp2,否则为exp3.
举例: