位运算
数据的存储
整数数据的存储
- 符号位
- 最高位,最左边一位
- 正数
- 原码、反码、补码相同
- 符号位为0,其余各位表示数值
- 两个字节(2*8位,其中一位符号位)的存储单元,最大能表示正数2^15-1
- 负数
- 原码、补码、反码不同
- 负数的原码
- 符号位为1
- 其余各位表示数值的绝对值
- 反码
- 符号位是1
- 其余各位对原码取反
- 补码
- 反码加1
- 两个字节(2*8位,其中一位符号位)的存储单元,最小能表示负数-2^15
- 数值一律用补码来表示和存储
- 使用补码,可以将符号位和数值域统一处理
- 加法和减法也可以统一处理
实型数据的存储
不考
符号位 阶码 尾数
基本数据类型
整型
名称 | 类型名 | 字节数 | 数据长度 | 取值范围 |
---|---|---|---|---|
字符型 | char | 1 | 8w | |
短整型 | short | 2 | 16位 | |
整型 | int | 4 | 32位 | |
长整型 | long | 4 | 32位 | |
long long | 64位 | |||
无符号型 | 区间长度一样,最大数变大从0,开始 | |||
单精度 | float | 4 | 32位 | 大概10^38 |
双精度 | double | 8 | 64位 | ±10^-308~10^308 |
整型常量
想要输出16进制数,只需要保证相应格式%x即可,后面的数值用任意一种形式表示即可
十进制 | 首位不能是0 | %d %u | |
---|---|---|---|
八进制 | 首位必须是0 | %o | |
十六进制 | 首位是0x | %x |
==跳过了123-130页==
输入输出
%md
- 输出宽度为m,包括符号位
- 数据实际宽度(含符号位)小于m,左端补空格
- 大于m,按实际位输出
- 右对齐
- %0md 左侧不足位用0填充
%-md
- 左对齐
double型输入时必须用%lf或%le
表达式
算术运算符
单目-一个操作数
双目-两个
自增和自减运算符
自增和自减运算符的对象只能是变量,不能是常量或表达式
!结合性
!按照运算符的优先级从高到低计算
!对于一个操作数,两侧哪个运算符优先级高就先与哪个结合
!优先级相同时,按结合性(结合方向)
!结合方向“从左到右”,操作数左面的运算符结合
!优先级
运算符种类 | 运算符 | 结合方向 | 优先级 |
---|---|---|---|
逻辑运算符 | ! | 右结合 | |
算术运算符 | ++ – + -(正负号) | 右 | |
* / % | 左 | ||
+ -(加减) | |||
关系运算符 | < > | ||
== != | |||
逻辑运算符 | && | ||
|| | |||
条件表达式 | ?: | 右结合 | |
赋值运算符 | 右结合 | ||
逗号表达式 | , | 左结合 |
- a+++b是 (a++)+b
赋值表达式
- 赋值表达式的值是运算符左侧变量的值
- 自动类型转换
- 赋值类型
- 右侧类型自动转换为左侧类型
- 运算精度可能会降低
- 非赋值类型
- 保证运算精度不降低
- 水平方向&竖直方向
- 赋值类型
x * =y-3 ===== x=x * (y-3)
关系表达式
关系运算符连接,结果是一个逻辑量
3<=x<=5 ===== (3<=x)<=5
逻辑表达式
逻辑运算符连接,结果也是一个逻辑量
优先级: 非 与 或
a||3+10&&2 等价于 a || ( ( 3 + 10 ) && 2 )
! ( x == 2 ) 逻辑表达式
! x == 2 等价于 ( ! x ) == 2 关系表达式,值恒为0
!注意与和或的 短路现象!
条件表达式
运算过程与if-else类似,条件运算符是右结合,多个同级运算符时先计算右边的
如果后面两个表达式类型不同,要根据类型自动转换规则确定条件表达式的类型
n>0?2.9:1; n为负数是结果是1.0
a>b?a:c>d?c:d (a>b)?a:((c>d)?c:d)
逗号表达式
从左到右依次计算表达式1-n的值,将表达式n的值和类型作为逗号表达式的类型
位运算
运算符 | 优先级 | |
---|---|---|
~ | ||
>> << | 移位运算不改变原操作数的值 | |
& | ||
^ | ||
| | ||
&= |= ^= >>= <<= |
操作数只能是整型or字符型以及他们的变体
区分逻辑运算和位运算
关于位运算的骚操作
异或
a^a = 0
a^~a = 二进制全1
~(a^~a) = 0
a^=b^=a^=b 交换a和b的值
同一变量与另一变量和其异或值异或等于另一个数,如(a^b)^b=a
移位
- 循环移位
- 移入的等于移出的
- 逻辑移位
- 移出的丢失,移入的为0
- 算术移位
- 左移,右边补0,左边舍弃
- 右移,左端空位用最高位符号位填补,右边舍弃
- 也有人说只有左端第一位是符号位填补,其他空位补0
int a=-2,b=1,c=0;
c |= (a >> 1) + ~b & a + 1;
1
2 printf("%d", c) ;
-3
~b = -2
因为数均由补码表示,负数的补码是反码加1,用于加法
反正正数x取反得到的就是 -x-1