数在内存中是以补码的形式进行存储的,而此节的知识点中有些操作是对补码进行的操作。
看到这个标题是不是理解呢?操作符是什么,是用来干什么的?但其实在前面学习C语言的过程中我们已经见过一些操作符,比如+ - * % / =等等,而今天我们会将操作符进行分类,详细介绍不同的操作符。
一、算术操作符
在学习C语言的过程中,+ - * % / 这五个操作符应该很熟悉了吧,所以就大概介绍一下吧。
1、+ - *分别对应数学中的加减乘,既能对浮点型进行运算,也能对整型进行运算。
2、% / 这两者就有很大的差异,首先 / 是求商而不是求余数,他的操作数据类型跟+ - * 是一样的,而 % 为取模运算符,左右两边的操作数必须是整型且其为求余数而不是商。
int a=9,b=2,c=0,d=0;
c=9/2;//值为4
d=9%2;//值为1
由此可见 / 和%的差距还是挺大的。
二、移位操作符
移位操作符有两种,分别是左移位(<<)和右移位(>>)。而移位的方案也有两种:一种是逻辑移位,另一种是算术移位。
左移位:
在左移位操作中,逻辑移位和算术移位的方法是一样的,都在右边空缺的地方添零。
例如:
char a=12;
a=a<<2;
a的原码,反码,补码 | 00001100 |
a<<2 00 | 001100 00 |
此时a的补码向左移了两位,空出来的用0补,所以现在a的补码为00110000,对应的值为48;
char a=-12;
a=a<<2;
a的补码 | 11110100 |
a<<2 11 | 110100 00 |
此时a的补码向左移了两位,空出来的用0补,所以现在a的补码为11010000,对应的值为-48;
右移位:
在逻辑移位方案中还是补零,在算术移位方案中补的数由符号位决定。对正数影响不大。
1、逻辑移位:
char a=-12;
a=a>>2;
a的补码 | 11110100 | |
a>>2 | 00 111101 | 00 |
在补码的左边补了0,现在补码00111101对的值为67。
2、算数移位
char a=-12;
a=a>>2;
a的补码 | 11110100 | |
a>>2 | 11 111101 | 00 |
在补码的左边补了1,现在补码11111101对的值为-3。
目前大多数认可也采用的方式为算术移位。
三、位操作符
& | ^ ~都是位操作符,今天我们也来详细介绍这几种操作符。
&
该操作符名为按位与,在这里它和scanf中的作用是不一致的,&在scanf中是取地址,而在这,它是对数在内存中的形式进行处理。对于它的使用,即为都为1时才为1,否则为零。
char a=7,b=5,c;
c=a&b;
//a的补码为00000111
//b的补码为00000101
//c 00000101
则推出c的补码为00000101,对应的值为5,所以c的结果为5;
|
该操作符名为按位或,它是对数在内存中的形式进行处理。对于它的使用,即为都为0时才为0,否则为1。
char a=7,b=5,c;
c=a|b;
//a的补码为00000111
//b的补码为00000101
//c 00000111
则推出c的补码为00000111,对应的值为7,所以c的结果为7;
^
该操作符名为按位异或,它是对数在内存中的形式进行处理。对于它的使用,即为相同为0,否则为1。
char a=7,b=5,c;
c=a^b;
//a的补码为00000111
//b的补码为00000101
//c 00000010
则推出c的补码为00000010,对应的值为2,所以c的结果为2;
~
该操作符名为按位取反运算符,它是对数在内存中的形式进行处理。对于它的使用,包括符号位,按位取反。
char a=0;
a=~a;
//a的补码为00000000
//~a的补码为11111111
// 原码为10000001
则此时a的原码为10000001,即值为-1;
四、赋值操作符
一般赋值:
赋值操作符即为“=”,他是表达式的一种,而不是某种类型的语句。所以只要是有出现表达式的地方,都允许进行赋值。
x=y+2;
上面的语句包含两种操作符:+和=。根据优先级,先进行+,再进行赋值。
再举例:
a=x=y+1;
这是连续赋值,相当于下面的代码:
x=y+1;
a=x;
但是为了方便理解,我们一般会写成下面这种形式。
复合赋值符:
比如+= %= &= 这些是前面操作符的复合形式。我们只介绍+=,其他的类推。
代码举例:
char a=10,b=9;
a+=b;
这串代码相当于下面的代码:
a=a+b;
最终得出来的a的值为19;
但是有时候为了减少代码会写成下面的形式。
五、单目操作符
C语言有一些单目操作符,也就是只接受一个操作数的操作符,像前面的~。除了这个还有! ++ - & sizeof -- * (类型)。
!
该操作符即执行逻辑反操作:如果操作数为真,其结果为假;如果操作数为假,其结果为真。他其实和条件操作符一样,产生的结果为0或1;
char a=1;
if(!a)
{
printf("haha");
}
else printf("hehe");
这个代码的结果为hehe。
++ --
这俩成为自增 自减;执行一次,数的结果+1,或者-1。
char a=0,b=0,c=0,d=0;
printf("%d",--a);
printf("%d",b--);
printf("%d",++c);
printf("%d",d++);
上面的值分别为-1 0 1 0;为什么呢,这俩操作符是右结合性,++ -- 在后面是先用a,在自增或者自减,而++ -- 在前面是先自增 自减再打印;
sizeof
该操作符是为了判断他的操作数的长度,以字节为单位表示,操作数既可以是表达式也可以是两边加上括号的类型名。
举例:
char a;
sizeof(int);
sizeof(a=1);
但是打印sizeof的返回数值时,我们需要用%zd 使用%d不准确,详情可看c plus plus官网。
printf("%zd",sizof(int));
但是值得我们注意的是,sizeof后面的括号内并不会计算,举例:
int a=9;
printf("%zd",sizeof(a=a+4));
printf("%d",a);
第二个printf的值还是9,并不会变。
*
这个为间接访问操作符,它一般是和指针一起使用的,用于访问指针所指向的值。
(类型)
此类操作符被称为强制类型转换,例如:
int a=0;char b;
b=(char)a;
- +
-操作符产生操作数的负值,跟数学中的负号是一样的,+啥作用没有 就是为了跟 - 操作符配对。