文章大致内容如下,会针对不同类型的操作符进行解释:
操作符的类型大致可以分为图中的所示的10种,图中给出了不同类型操作符中的一些操作符的例子。
1.算术操作符: + - * %
对于算术操作符,需要注意的就是对‘/‘和’%‘的使用,当用到’/‘来进行除法运算时,需要注意以下两点:
1.整数除法(除号的两端都是整数)
2.浮点数除法(除号的两端只要有一个小数就执行小数除法)
例如,想要得到7%2 = 3.5这个结果,如果按照下面的格式进行除法;
int a = 7/2;
printf("%d", a);
会发现并不能得到3.5这个结果
如果再把printf函数中的打印类型从%d,改成%lf,并且在定义变量a时,采用double类型而非Int类型,则:
double a = 7/2;
printf("%lf", a);
得到的结果依旧不是3.5
当把两个数种随机一个改成小数形式时,即:
double a = 7.0/2;
printf("%lf", a);
打印结果就变成了预期中的3.5
对于’%‘,在前面的文章中曾多次引用,名称是取模操作符,作用是用来获取余数,且如果定义除数的大小是n,被除数大小为>0的任意整数,则余数的范围是0~n-1.对于取模操作符,在使用时需要注意的一点就是取模操作符,即%的两个操作数必须是整数
2.移位操作符: >> <<
移位操作符,需要注意这里的移位的含义,即:移动的是数据二进制位的位数
在介绍移位操作符是如何对数据的二进制位进行更改前,先给出一个数的源码,反码,补码
int a = 15;
//原码:00000000000000000000000000001111
//反码:00000000000000000000000000001111
//补码:00000000000000000000000000001111
//对于正整数来说,他的原码、反码、补码相同
int a = -15;
//原码:10000000000000000000000000001111
//反码:11111111111111111111111111110000
//补码:11111111111111111111111111110001
//最高位1表示该数为负数,反码则是除了最高位的数不懂,
//其他数位的数全部取反,补码则是在反码的最后一位加1
同时,对补码进行一定补充:
1.整数在内存中的存储是补码
2.位移计算的时候也是按照补码进行计算。
上面说到,移位是指移动数据的二进制位,下面给出一个例子:
int a = 15;
int b = a >> 1;
printf("%d",b);
printf("%d",a);
结果如下:
可以看到,在对变量b中的a进行移位操作后,只是在b的表达式种,a的大小发生了变化,但是变量a自身的大小并没有发生变化。对于a是如何从15变成7的,下面将给出一幅图进行解释:
对于右移位操作符而言,可以看作二进制数是被一个长度和二进制数本身长度一样的盒子封装的,在右移后,舍弃最右边的一个数字,并且在开头补上原来的符号位。
同样,对于左移操作符,下面也给出一个例子:
int a = 3;
int b = a << 1;
printf("%d",b);
printf("%d",a);
同样,左移操作符也是对数的补码进行移位,与右移操作符不同的是,左移操作符只需要在最后一个补上0即可。
3.位操作符 & | ^
//& 按位与
//| 按位或
//^ 按位异或
3.1:按位 & (与)
与移位操作符相同,位操作符同样作用于数的二进制位,并且对应两个二进制位有0则是0,全是1才为1,下面给出一个例子;
int a = 3;
//对应二进制位:00000000000000000000000000000011
int b = -5;
//对应二进制位:10000000000000000000000000000101
反码: 10000000000000000000000000001010
补码: 10000000000000000000000000001011
int c = a&b;
a:00000000000000000000000000000011
b:10000000000000000000000000001011
c:00000000000000000000000000000011
c = 3;
3.2:按位 | (或)
同理,也是作用于二进制位,不过按位‘|’是对两个二进制位,有1则为1,全是0才能得到0
int a = 3;
//对应二进制位:00000000000000000000000000000011
int b = -5;
//对应二进制位:10000000000000000000000000000101
反码: 10000000000000000000000000001010
补码: 10000000000000000000000000001011
int c = a|b;
a:00000000000000000000000000000011
b:10000000000000000000000000001011
c:10000000000000000000000000001011//注意,此处为补码,c的结果还需要翻译成原码
c = -5;
3.3:按位 ^ (异或)
对两个二进制,相同为0,相异为1
int a = 3;
//对应二进制位:00000000000000000000000000000011
int b = -5;
//对应二进制位:10000000000000000000000000000101
反码: 10000000000000000000000000001010
补码: 10000000000000000000000000001011
int c = a^b;
a:00000000000000000000000000000011
b:10000000000000000000000000001011
c:10000000000000000000000000001000
c = 8;
对于‘^’(异或)操作符,可以用它来实现一些功能,例如下面这个例子:
再不创建第三方变量的情况下,交换两变量的内容:
这里就可以用到‘^’操作符来完成,具体代码如下:
int main()
{
int a = 3;
int b = 5;
a = a^b;
b = a^b;
a = a^b;
return 0;
}
结果如下:
至于为什么可以用异或操作符来达成这种效果,接下来给出解释:
首先,我们假设变量a的二进制数为:101,b的二进制数为:011
进行a^b^a,具体过程如下:
a = 101;
b = 011;
a^b = 110;
101
011
a^b^a = 011
110
101
会发现,a^b^a的结果就是b
如果再进行a^a,因为异或操作符的特性,可以知道,a^a=0;0^任何数都是它本身,所以,上面的a^b^a,可以看作 a^a^b,即,异或满足交换律,所以上面交换两数的代码,可以进行以下解释:
int a = 3;
int b = 5;
a = a^b;
b = a^b; //此时可以看作b = a^b^b = a
a = a&b; //此时可以看作a = a^b^a = b
因此,上述代码可以在不创建第三方临时变量的情况下,交换两变量中的值
4.赋值操作符(=)(使用简单,不做介绍)
5.单目操作符
5.1 !(逻辑反操作)
!起到的作用就是可以把真变成假,把假变成真,例如:
int main()
{
int flag = 0;
if(flag)
{
printf("hehe");
}
if(!flag)
{
printf("haha");
}
return 0;
}
结果如下:
可以看到,因为定义flag = 0; 所以第一个if中,flag= 0;判定为假,所以不打印,在第二个if中,使用了逻辑反操作符,flag此时等于1,所以if中的内容为真,因此打印了haha
5.2 &(取地址操作符) *(解引用操作符)
均用于指针,关于指针的具体内容可去卡面的文章查看
5.3 ~(按位取反操作符)
下面通过一个例子来解释~的作用:
int main()
{
int a = 0;
printf("%d",~a);
return 0;
}
结果如下:
和其他操作符一样,按位取反操作符也是针对于数的二进制位进行操作的(针对于补码)
例如上面0的二进制位是:00000000000000000000000000000000(原码反码补码相同),进行按位取反的操作时,变成 1111111111111111111111111111111111111(也是补码),再解析回原码,则为 10000000000000000000000000000001
6.关系操作符(>= <= )不做解释
7.逻辑操作符( &&并且 ||或者 )