要点一:虚拟地址空间
1.大多数计算机使用8位的块,或者字节(byte),作为最小的可寻址的存储器单位,而不是在存储器中访问单独的位。
2.机器级程序将存储器视为一个非常大的字节数组,称为虚拟存储器(virtual memory),存储器的每个字节都由一个唯一的数字来标识,即它的地址,所有可能地址的集合称为虚拟地址空间(virtual address space)。
要点二:二进制,八进制,十进制,十六进制
进制转换 | ||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
二进制 | 0000 0000 | 0000 0001 | 0000 0010 | 0000 0011 | 0000 0100 | 0000 0101 | 0000 0110 | 0000 0111 | 0000 1000 | 0000 1001 | 0000 1010 | 0000 1011 | 0000 1100 | 0000 1101 | 0000 1110 | 0000 1111 |
八进制 | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 010 | 011 | 012 | 013 | 014 | 015 | 016 | 017 |
十进制 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
十六进制 | 0X0 | 0X1 | 0X2 | 0X3 | 0X4 | 0X5 | 0X6 | 0X7 | 0X8 | 0X9 | 0XA | 0XB | 0XC | 0XD | 0XE | 0XF |
进制之间的转换不作介绍,有多种方法,根据个人习惯选择。
要点三:数据大小
要点四:寻址和字节顺序
字节大端顺序存储or字节小端顺序存储
字节大端顺序存储:高位字节存储于低位地址,低位字节存储于高位地址
字节小端顺序存储:高位字节存储于高位地址,低位字节存储于低位地址
字节大端顺序存储(0X01234567) | |
........ | ........ |
0X100 | 01 |
0X101 | 23 |
0X102 | 45 |
0X103 | 67 |
......... | ......... |
字节小端顺序存储(0X01234567) | |
....... | ...... |
0X100 | 67 |
0X101 | 45 |
0X102 | 23 |
0X103 | 01 |
........ | ......... |
如何判断是字节大端顺序存储还是字节小端顺序
程序如下:
字节存储顺序问题在网络编程中数据传送会遇到,在网络上传输数据时,由于数据传输的两端可能对应不同的硬件平台,采用的存储字节顺序也可能不一致,因此TCP/IP协议规定了在网络中必须采用网络字节顺序(大端模式)。为此在linux网络编程中专门提供了转换函数:
#include<netinet/in.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
htonl 表示 host to network long,用于将主机unsigned int 型数据转换成网络字节数据;htons 表示 host to network short,用于将主机unsigned short 型数据转换成网络字节数据;
ntohl 和 ntohs 功能相反。
要点五:字符串编码:ASCII,Unicode,UTF-8
有关字符编码问题,网上有很多资料和讨论,大家可以参考。
要点六:布尔代数
代数运算 | |
运算 | 结果 |
a | 01101001 |
b | 01010101 |
~a | 10010110 |
~b | 10101010 |
a&b | 01000001 |
a|b | 01111101 |
a^b | 00111100 |
布尔运算有很多应用,也有一些使用技巧。
例如:无符号整型12345的二进制表示中有多少个1?
程序如下:
网络的子网掩码运算也采用布尔运算,布尔运算的使用在很多地方均可见到,故不多讲。
要点七:c语言中的位级运算
练习题2.10答案
步骤 | *x | *y |
初始 | a | b |
第一步 | a | a^b |
第二步 | b | a^b |
第三步 | b | a |
练习题2.11答案
1.first和last的值都为a[k]
2.a[k]^a[k] = 0
3.在代码中加个if判断语句,若a[first] == a[last],不做交换。
练习题2.12 答案
1.x&0xFF
2.~(x|0xFF) + (x&0xFF)
3.x|0xFF
练习题2.13答案
int bool_or(intx,int y)
{
int result = bis(x,y);
return result;
}
int bool_xor(int x,int y)
{
int result = bis(bic(x,y),bic(y,x));
return result;
}
要点八:c语言中的移位运算
移位运算符的操作符优先级问题:比加法和减法的优先级低,从左到右结合。
1 << 2+3 << 4 等价于(1 << (2+3))<< 4
要点九:补码编码
[1101]补= -1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0 = -3
w位补码的表示范围(2^w-1 - 1,-2^w-1)
要点十:有符号数与无符号数之间的转换
对大多数c语言的实现而言,对有符号数和无符号数的转换的一般规则是:数值可能会改变,但位模式不会变。
c语言中的有符号数和无符号数之间的转换
转换公式:
注:T2U 补码转无符号;U2T 无符号转补码
验证程序如下: