16进制 地址形式
0 1 2 4 5 6 7 8 9 A B C D E F
F是15
0x:16进制标志
2进制:内存存储数据
0 1
进制转换
1.基数相加法
2.反转取余法
这两种方法都能单独转,但是为了计算方便,一般是
10进制转其他进制:反转取余法
其他进制转10进制:基数相加法
1.基数相加法
- 0XAB2 ->10进制数
各个位上的数乘他的基数 比如十进制1234 = 4 * 10^0 + 3 * 10^ 1+2 * 10^2 + 4* 1^3
那么0XAB2=2* 16^0+ B* 16^ 1+A* 16^2 (B=11,A=10) - 八进制7235 ->10进制数
5* 8^0 + 3* 8^1+ 2 *8^2 +7 *8^3 - 0XAB2 -> 8进制数
分析:十六进制转10进制:0XAB2=2* 16^0+ B* 16^ 1+A* 16^2 (B=11,A=10)
转8进制,就不乘以16的n次方了,因为16在8进制里是20,所以,乘20的n次方。
B是八进制的13,A是八进制的12
如下:
0XAB2=2* 20^0+ 13* 20^ 1+12* 20^2
2.反转取余法
转几进制就除以几
234 转成8进制:

3.进制互相转换

16-2

2-16

位操作
位操作的两种方式:位运算符、位字段
注意:位运算只支持整数
- ~:按位取反
一个数的二进制的0、1交换
&:按位与
|:按位或
^:按位异或
<<和>> :移位运算符
&=、|=、^=、>>=、<<=
~:按位取反
正数:补码是本身
负数:补码:数据位按位取反再加1(符号不变)
注意⚠️:最高位是符号位,不参与按位取反加一中的取反
#include "c3.h"
int main(int argc, char *argv[]) {
//分析:
//整数按照补码形式进行存储的
//正数的补码是本身,负数的数据位补码是按位取反再加1
//负数最高位存储是1,正式最高位存储是0
//-123二进制是:1(符号位) 111 1011 ,按位取反加1:1(符号位不变)000 0100,
// 再加1,1000 0101,也就是-123在内存中存储的数据。
//b的话就是a的存取取反:即1000 0101取反0111 1010
// 0111 1010:122
char a = -123;
char b = ~a;
printf("%d\n", b);//122
// --------------------
//123在内存中的存储是:0(符号位) 111 1011
//取反得到b:1 000 0100
//b的存储数据是1 000 0100,那么10进制数就是:先-1,再按位取反
//即:1 000 0011,再按位取反:0 0111 1100:即124,符号位是0 则是-124
char c = 123;
char d = ~c;
printf("%d\n", d);//-124
return 0;
}
&:按位与
只有1&1 =1,
其他都是0
1010 1111&1100 1010
得:1000 1010
#include "c3.h"
int main(int argc, char *argv[]) {
//分析:79的二进制:0 100 1111 ,-23的二进制:1 001 0111
//-23在内存中存取数据是:数据位按位取反+1 :1 110 1001
//0 100 1111 & 1 110 1001 得 0 100 1001 得:+73
char a = 79;
char b = -23;
char c = a & b;
printf("%d\n", c);//73
return 0;
}
|:按位或
只有0|0得0,
其他都是1
1010 1111 | 1100 1010
得:1110 1111
#include "c3.h"
int main(int argc, char *argv[]) {
//分析:79的二进制:0 100 1111 ,-23的二进制:1 001 0111
//-23在内存中存取数据是:数据位按位取反+1 :1 110 1001
//0 100 1111 | 1 110 1001 得 1 110 1111
// 因为上面存储的数据是负数,所以得到真正的数据:-1 按位取反
//即:1 0110 1110 取反:1 0001 0001,即-17
char a = 79;
char b = -23;
char c = a | b;
printf("%d\n", c);//-17
return 0;
}
^:按位异或
不同为1,
相同为0
1010 1111 ^ 1100 1010
得:0110 0101
注意:C中pow是平方,sqrt是开方
#include "c3.h"
int main(int argc, char *argv[]) {
//分析:79的二进制:0 100 1111 ,-23的二进制:1 001 0111
//-23在内存中存取数据是:数据位按位取反+1 :1 110 1001
//0 100 1111 ^
1 110 1001 得 1010 0110
// 因为是负数,所以真正的数据是-1 取反
//即 1 010 0101 取反:1 101 1010 得-90
char a = 79;
char b = -23;
char c = a ^b;
printf("%d\n", c);//-90
return 0;
}
<<和>> :移位运算符
- a<<2: 位左移
- 2>>a: 位右移
技巧⚠️:
a<<n,相当于乘以2的n次幂;
a>>n,a如果是非负数,相当于除以(/取整)2的n次幂
1000 0101 位左移两位

int main(int argc, char *argv[]) {
//分析:a的存储形式就是他本身:0010 1101
//坐移动两位:变成:1011 0100
//因为1 所以是负数:-1取反:所以是1100 1100 即-76
char a = 45;
char b = a << 2;
printf("%d\n", b);//-76
return 0;
}
1000 0101 位右移两位
如果正数:位右移2位,最高位补俩0
如意负数:位右移2位,有的系统补俩0,有的系统补俩1(windows是补11,macbook pro测试也是补11)
//正数的时候:
int main(int argc, char *argv[]) {
//分析:a的存储形式就是他本身:0010 1101
//坐移动两位:变成:0000 1011 即11
char a = 45;
char b = a >>2;
printf("%d\n", b);//11
return 0;
}
//负数的时候,我的电脑是最高位补1
#include "c3.h"
int main(int argc, char *argv[]) {
//分析:a的存储形式就是他的取反+1:
// -45:1010 1101,取反+1:1101 0011
//坐移动两位:变成:1111 0100
//因为是负数,1111 0100 是他的存储数据,他真正的数据是:
// -1 再取反:-1: 1111 0011 取反:1000 1100 即-12
char a = -45;
char b = a >>2;
printf("%d\n", b);//-12
return 0;
}
技巧⚠️:
a<<n,相当于乘以2的n次幂;
a>>n,a如果是非负数,相当于除以(/取整)2的n次幂
位运算速度远远大于普通运算
#include "c3.h"
int main(int argc, char *argv[]) {
char a = 6;
char b = a << 3;//a左移动2位,相当于,6*2^3=48
printf("%d\n", b);//48 :
char c = 48;
char d = c >> 3;//非负数a右移动3位,相当于,48/(2^3)
printf("%d\n", d);//6
return 0;
}
&=、|=、^=、>>=、<<=
跟+= 、-=一样。
a^=b :a=a^b;
...
2.位字段
这个方法移植性不是很好,位运算完全可以实现字段的所有功能,所以位字段了解为主。

网友评论