深入计算机系统第二章 第一节
深入计算机系统第二章 第一节

深入计算机系统第二章 第一节

第二章——信息的表示和处理

三种重要的数字表示

  • 无符号(unsigned)编码基于传统的二进制表示法, 表示大于或等于0的数字.
  • 补码(two’s-complement)编码是表示有符号整数最常见的方式.
  • 浮点数(floating—point)编码是表示实数的科学计数法的以2为基数的版本.

由于表示的精度有限, 浮点运算是不可结合的.

使用命令行指定C版本

linux> gcc -std=c11 main.c

信息存储

机器级程序将内存视为一个非常大的数组, 称为虚拟内存, 所有可能地址的集合就称为虚拟地址空间.

C语言中的一个指针的值都是某个存储块的第一个字节的地址.

16进制表示法

在C语言中, 以0x或0X开头的数字常量被认为是十六进制的值.

16进制和10进制转换

辗转相除法.

字数据大小

对于一个字长为w位的机器而言, 虚拟地址的范围为0\sim 2^w -1, 程序最多访问2^w个字节.

longchar指针在字长为32位与64位的机器中的字节数分别为4和8.

C标准不保证char为有符号数(尽管大多数编译器将其视为有符号数).

寻址和字节顺序

两个规则: 对象的地址, 如何排列这些字节.

几乎在所有的机器上, 对象的地址为所使用字节最小的地址.

最低有效在最前面的方式称为小端法, 最高有效字节在最前面的方式称为大端法.

小端法显示数据顺序代码

#include <stdio.h>

typedef unsigned char* byte_pointer;

void show_bytes(byte_pointer start, size_t len) {
    size_t i;
    for (i = 0; i < len; i++)
        printf(" %.2x", start[i]);
    printf("\n");
}

void show_int(int x) {
    show_bytes((byte_pointer)&x, sizeof(int));
}

void show_float(float x) {
    show_bytes((byte_pointer)&x, sizeof(float));
}

void show_pointer(void* x) {
    show_bytes((byte_pointer)&x, sizeof(void*));
}

void test_show_bytes(int val) {
    int ival = val;
    float fval = (float)val;
    int* pval = &ival;
    show_int(ival);
    show_float(fval);
    show_pointer(pval);
}

void main() {
    const char* s = "abcdef";
    test_show_bytes(12345);
    printf("%.2x", 12345);
}

结果为

 39 30 00 00 (内存中的表示形式)
 00 e4 40 46
 a0 f9 f7 00
 3039(实际应该是这样的)

布尔代数的有趣性质

(a\hat{\space\space}b) \hat{\space\space} a=b

可以用来做无需第三变量的swap:

void inplace_swap(int *x, int *y){
    *y = *x ^ *y;
    *x = *x ^ *y;
    *y = *x ^ *y;
}

移位运算

向右移位运算分为逻辑右移算数右移, 逻辑右移用0补齐左空位, 算术右移用1补齐左空位(2次幂).

对无符号数, 必须为逻辑右移.

发表回复

您的电子邮箱地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据