计算机基础知识

一、数据的机内表示

1. 二进制表示

  • 机器数
    • 由于计算机中符号和数字一样,都必须用二进制数串来表示,因此,正负号也必须用0、1来表示。
    • 用最高位0表示正、1表示负, 这种正负号数字化的机内表示形式就称为“机器数”,而相应的机器外部用正负号表示的数称为“真值”,将一个真值表示成二进制字串的机器数的过程就称为编码。
  • 原码
    • 原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值

[+1]原 = 0000 0001

[-1]原 = 1000 0001

第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:

[1111 1111 , 0111 1111]

[-127 , 127]

原码是人脑最容易理解和计算的表示方式

  • 反码
    • 反码的表示方法是:
      • 正数的反码是其本身;
      • 负数的反码是在其原码的基础上, 符号位不变,其余各个位取反

[+1] = [00000001]原 = [00000001]反

[-1] = [10000001]原 = [11111110]反

可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算

  • 补码
    • 补码的表示方法是:
      • 正数的补码就是其本身
      • 负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1。 (即在反码的基础上+1)

[+1] = [00000001]原 = [00000001]反 = [00000001]补

[-1] = [10000001]原 = [11111110]反 = [11111111]补

  • 定点数与浮点数
    • 定点数是小数点固定的数。在计算机中没有专门表示小数点的位,小数点的位置是约定默认的
    • 固定在机器数的最低位之后:定点纯整数
    • 固定在符号位之后:为定点纯小数
    • 定点数表示法简单直观,但是数值表示的范围太小,运算时容易产生溢出
  • 浮点数是小数点的位置可以变动的数。为增大数值表示范围,防止溢出,采用浮点数表示法。浮点表示法类似于十进制中的科学计数法。
  • 在计算机中通常把浮点数分成阶码和尾数两部分来表示,其中阶码一般用补码定点整数表示,尾数一般用补码或原码定点小数表示。为保证不损失有效数字,对尾数进行规格化处理,也就是平时所说的科学记数法,即保证尾数的最高位为1,实际数值通过阶码进行调整
  • 阶符表示指数的符号位、阶码表示幂次、数符表示尾数的符号位、尾数表示规格化后的小数值。

N = 尾数×基数阶码(指数)

2. 位(Bit)、字节(Byte)、字(Word)

  • 字节:8个二进制位构成1个"字节(Byte)",它是存储空间的基本计量单位。1个字节可以储存1个英文字母或者半个汉字,换句话说,1个汉字占据2个字节的存储空间。
  • 字:"字"由若干个字节构成,字的位数叫做字长,不同档次的机器有不同的字长。例如一台8位机,它的1个字就等于1个字节,字长为8位。如果是一台16位机,那么,它的1个字就由2个字节构成,字长为16位。字是计算机进行数据处理和运算的单位。

3. 字节序

  • 字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有小端、大端两种字节顺序。
  • 小端字节序指低字节数据存放在内存低地址处,高字节数据存放在内存高地址处;
  • 大端字节序是高字节数据存放在低地址处,低字节数据存放在高地址处。
  • 基于X86平台的PC机是小端字节序的,而有的嵌入式平台则是大端字节序的。所有网络协议也都是采用big endian的方式来传输数据的。所以有时我们也会把big endian方式称之为网络字节序。

比如数字0x12345678在两种不同字节序CPU中的存储顺序如下所示:

Big Endian
低地址                                            高地址
---------------------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     12     |      34    |     56      |     78    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Little Endian
低地址                                            高地址
---------------------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     78     |      56    |     34      |     12    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

从上面两图可以看出,采用Big Endian方式存储数据是符合我们人类的思维习惯的

联合体union的存放顺序是所有成员都从低地址开始存放,利用该特性,就能判断CPU对内存采用Little-endian还是Big-endian模式读写。

示例代码如下:

union test{  
    short  i;  
    char str[sizeof(short)];  
}tt;  

void main()  
{  
    tt.i = 0x0102;  
    if(sizeof(short) == 2)  
        {  
            if(tt.str[0] == 1 && tt.str[1] == 2)  
                printf("大端字节序");  
            else if(tt.str[0] = 2 && tt.str[1] == 1)  
                printf("小端字节序");  
            else  
                printf("结果未知");  
         }  
    else  
        printf("sizof(short)=%d,不等于2",sizeof(short));  
}

4.字节对齐

现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。

为什么要进行字节对齐?

  • 某些平台只能在特定的地址处访问特定类型的数据;
  • 最根本的原因是效率问题,字节对齐能提⾼存取数据的速度。

比如有的平台每次都是从偶地址处读取数据,对于一个int型的变量,若从偶地址单元处存放,则只需一个读取周期即可读取该变量,但是若从奇地址单元处存放,则需要2个读取周期读取该变量。

字节对齐的原则

  • 数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在 offset 为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。

  • 结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储。)

  • 收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值