概述
算数操作符
+ - * / %
以上操作符除 % 以外都可以对小数进行操作
用法举例
#include<stdio.h>
int main()
{
int a = 10;
int b = 3 ;
int c = 0 ;
c = a + b; //简单的加法 c = 10 + 3 = 13
c = a - b; //简单的减法 c = 10 - 3 = 7
c = a * b; //乘法 c = 10 * 3 = 30
c = a / b; //除法 c = 10 / 3 = 3 ( '/'只会获得除得的商值
c = a % b; //取模 c = 10 % 3 = 1 ( '%'只会获得最后的余数
return 0;
}
移位操作符
>>向右移位 <<向左移位
向左移位 <<
这里我们要将数值转化为二进制位
例如 a= 5,5的二进制位为 00000000 00000000 00000000 00000101
那么 a<<1,就是a向左移1位 。那么他的二进制就会整体向左移动1位
具体变化如下
我们看到 向左移位后 最左边的二进制位被丢了出去 而后面缺少了一个二进制位
处理方式为 第一个被丢出去的二进制位被舍去 末尾补0
那么最后的输出结果为 000000000000000000001010
其代表的数值为 10 , 即a=5,a<<1 的值为 10
那么如果a是一个负数呢?
这里需要用到另一个知识
负整数在二进制中不仅有原码 ,还有反码和补码
以 -5 举例 , -5的二进制为
100000000000000000000101
这里我们注意到 二进制的最高位为1 ,而不是0。
二进制中最高位是1则说明其为负数。
最高位是0则说明其为正数。
但二进制在内存中所存储的是二进制的补码,所以我们在计算时需要进行转换。
正数的原码,反码和补码相同 ,而负数则需要原码 - 反码 - 补码的转换。
反码的转化:符号位保持不标,其他位按位取反。得出反码为
111111111111111111111010
最后。将反码+1得出补码, 即 -5在内存中所储存的二进制为
111111111111111111111011
我们在操作二进制位时,是在内存中使用补码进行操作的
回归正题,我们操作补码向左移位 首位丢弃,末尾补0,得到反码为
111111111111111111110110
再将补码转换为原码
100000000000000000001010
其最终结果为 -10
向右移位 >>
向右移位因为涉及到首位的补充 ;所以分两种情况
逻辑移位:左边移入的位用0填充
算术移位:左边移入的位由原先该值的符号位决定,符号位为1则移入的位均为1,符号位为0则移入的位均为0,这样能够保持原数的正
负形式不变。
例如:10010110 >> 2
逻辑移位:00100101
算术移位:11100101
*无法移位负数位 例如:a<<-5 //err
位操作符
& | ^
& 按位与
| 按位或
^ 按位异或
按位与 &
#include<stdio.h>
int main()
{
int a = 3; // 000000000000000000000011
int b = 5; // 000000000000000000000101
int c = a & b; // 000000000000000000000001
printf("%dn",c); // 按位与:指二进制位有0则为0,全1则为1。
return 0; // c = 1
}
按位或 |
#include<stdio.h>
int main()
{
int a = 3; // 000000000000000000000011
int b = 5; // 000000000000000000000101
int c = a | b; // 000000000000000000000111
printf("%dn",c); // 按位或:指二进制位有1则为1,全0则为0。
return 0; // c = 7
}
按位异或 ^
#include<studio.h>
int main()
{
int a = 3; // 000000000000000000000011
int b = 5; // 000000000000000000000101
int c = a ^ b; // 000000000000000000000110
printf("%dn", c); // 按位异或:指二进制位相同为0,相异则为1。
return 0; // c = 6
}
赋值操作符
= += -= *= /= &= ^= |= >>= <<=
以上操作符 除 '=' 均为复合赋值符。
=
'='我们不难理解 只是简单的赋值。
int a = 10; 即给变量a赋予了一个大小为10的值。
+= -= *= /=....
此类赋值符仅是一个简化写法 其实很好理解
比如
#include<stdio.h>
int main()
{
int a = 0;
a = a + 1; // a += 1
a = a - 1; // a -= 1
a = a * 1; // a *= 1
a = a / 1; // a /= 1
//.....
return 0;
}
单目操作符
什么是单目操作符
单目操作符就是指仅操作单个变量的操作符
! - + & sizeof ~ -- ++ * (类型)
! 逻辑反操作
逻辑反即把真变成假,把假变成真。且真默认为1,假默认为0.
#include<stdio.h>
int main(void)
{
int a = 10;
a = !a; //10为真 逻辑反变为假
printf("a = %dn",a); //a = 0
int b = 0;
b = !b; //0为假 逻辑反变为真
printf("b = %dn", b); //b = 1
return 0;
}
- 负值
负值就是把正数变为负数 ,负数变为正数,不难理解。
#include<stdio.h>
int main(void)
{
int a = 10;
a = -a;
printf("a = %dn", a); // a = -10
int b = -10;
b = -b;
printf("b = %dn", b); // b = 10
return 0;
}
+ 正值
目前并未发现有什么用处(确信
不会改变数值
#include<stdio.h>
int main(void)
{
int a = 10;
a = +a;
printf("a = %dn", a); // a = 10
int b = -10;
b = +b;
printf("b = %dn", b); // b = -10
return 0;
}
& 取地址
取地址操作符
在指针操作中,该操作符的作用为提取变量的地址
#include<stdio.h>
int main()
{
int a = 0;
printf("%dn", a); //0
printf("%pn", &a); //00AFF8AC (该数值完全随机
return 0;
}
可见加上了取地址操作符就不再操作a本身,而是操作a的地址。
scanf中必须加&,否则编译器会报错
没有地址或不在内存中的内容不能取地址
详见指针https://blog.csdn.net/qq_63040618/article/details/120905544?spm=1001.2014.3001.5501https://blog.csdn.net/qq_63040618/article/details/120905544?spm=1001.2014.3001.5501
sizeof 操作数的类型长度(以字节为单位)
sizeof计算的是变量或类型所创建变量占据内存的大小 - 单位是字节
sizeof计算内存占用时 会计入 '