CSAPP笔记(第二章 信息的表示和处理)-01

概要

  • 无符号整数(unsigned)基于传统的二进制编码, 补码(two's-complement)是表示有符号整数最常见的方式, 浮点数(floating-point)是表示实数的科学计数法基数为2的版本
  • 以有限位的方式表示数字, 在计算时时常会超出表示范围(即溢出overflow), 这经常会导致系统安全漏洞, 遭受黑客攻击
  • 整数的表示范围较小, 是精确的; 浮点数的表示范围较大, 但是是近似的
  • C语言的演变: GNU C > ANSI C > ISO C90(C89) > ISO C99 > ISO C11(2011)

信息存储

  • 程序将内存视为一个大的字节数组, 称为虚拟内存(virtual memory), 每个字节都有一个地址, 所有可能地址的集合称为虚拟地址空间(virtual address space)
  • 我们将程序称为"32位程序"或"64位程序"时, 区别在于该程序是如何编译的, 而不是运行时的机器类型
  • 同样的类型在不同的机器和编译器下的大小是不一致的, 这导致移植问题. 程序开发时应尽量使用大小确定的数据类型, 或使用sizeof进行动态获取

大端法和小端法

一个对象, 如int类型, 可能占据多个字节的空间, 一般分配连续的地址空间进行存储. 对于这个对象, 有的机器选择从小到大存储, 有的从大到小存储, 分别为小端法和大端法. 如int类型的值0x01234567, 大端法(01-23-45-67), 小端法(67-45-23-01). Android和IOS是小端模式, 大多数Inter兼容机是小端模式. 这也会导致移植问题

表示字符串

C语言中字符串被编码位以一个null结尾的字符数组, 每个字符以一个标准编码(如ASCII)表示, 在任何系统上都得到同样的结果, 与字节顺序和字大小规则无关. 因而文本数据比二进制有更强的平台独立性. 所以为了二进制传输安全, base64编码会将二进制编码为64个常见且可打印的字符, 再进行传输, 虽然会增加传输的大小, 但传输的可靠性得到了保证, 常见于email传输中. 参考链接

整数表示

无符号整数编码B2Uw(Binary to Unsigned)

w位的无符号整数编码范围为[0, 2^w - 1]

有符号整数编码B2Tw(Binary to Two's-complement)

w位的有符号整数编码范围为[- 2^(w-1), 2^(w-1) - 1]

无符号数和有符号数的转换

C语言中的有符号数和无符号数

当执行一个运算时, 如果一个运算数是有符号数一个是无符号数, 那么C语言会隐式地将有符号数强制类型转换为无符号数, 并假设这2个数都是非负的来执行这个运算.

扩展一个数字的位表示

  • 无符号数的扩展, 直接高位补0
  • 补码数的扩展, 高位补最高位, 1011 = 1 1011 = 11 1011 = 111 1011 = -5

截断数字

关于有符号数和无符号数的建议

C语言中unsigned int的减法要特别注意, 一旦结果为负值, 预期是负值, 然后实际是很大的正整数, 很多逻辑就会出现问题.

另外一种情况是参数的不匹配, 如函数参数是int, 函数内部调用另外一个函数传的int, 而形参是unsigned int(如size_t), 传的值是负值就容易出问题.

猜你喜欢

转载自www.cnblogs.com/winwink/p/CSAPP_Note_Chapter2_Bit.html