CSAPP——第2章信息的表示和处理
第 2 章 信息的表示和处理
(用来记录一些一直困惑的点)
有关大端小端
书 P29 的两幅图比较形象的给出了0x01234567
大端法和小端法在内存中储存的样子,小端实际上就是将最低有效字节储存在内存中低地址(靠前面)的位置。
补充一句,当阅读像此类小端法机器生成的机器级程序表示时,经常会将字节按照相反的顺序显示。书写字节序列的自然方式是最低位字节在左边,而最高位字节在右边,这正好和通常书写数字时最高有效位在左边,最低有效位在右边的方式相反。
整数表示
有关补码原码
C 语言中有符号和无符号类型比较时,会隐式地将有符号参数强制类型转换位无符号数,并假设这两个数都是非负地,来执行这个运算,这会导致一些可能难以理解的比较结果。比如-1<0U
为假(因为\(T2U(-1) = UMax\)),以及2147483647 > (int) 2147483648U
为真。
另外,在视频的总结中还举了一个例子,循环for(unsigned int i = n-1; i>=0 ; i--)
会是无限的,因为 unsigned 总是被认为非负的(从\(0\) jump 到 \(UMax\))。同时更重要的,循环for(int i = n-1; i-sizeof(char) >= 0 ; i--
也会是无限的!,结合上面隐式转换,sizeof
返回的结果是 unsigned,导致循环终止判断的左表达式都会被隐式转换为 unsigned 再与\(0\)进行比较。如果我们只是看着这个程序,很难知道其崩溃的原因。
Summary Casting Signed <-> Unsigned: Basic Rules
- Bit pattern is maintained
- But reinterpreted
- Can have unexprected effects: adding or subtracting \(2^w\)
- Expression containing signed and unsigned int
- int is cast to unsigned!!
有关位模式的直觉- -
整数部分最后再次回到,Signed 和 Unsigned 的讨论,很多时候我们需要谨慎小心的使用 unsigned,比如视频中提到的用for (size_t i = cnt - 2; i < cnt ; i--)
写法习惯来避免在 loop index 中使用 unsigned 时出现问题,这样更加更加保险(因为 C 标准并没有给出溢出后情况如何,该循环的终止条件就是溢出)。size_t
defined as unsigned value with length = word size.
那最后,Why Should I Use Unsigned?
- Do Use When Performing Modular Arithmetic(Multiprecision arithmetic, Encryption)
- Do Use When Using Bits to Represent Sets(Logical right shift, no sign extention)
Representations in memory, pointers, strings
Byte-Oriented Memory Organization
- Programs refer to data by address
- Conceptually, envision it as a very large array of bytes
- An address is like an index into that array (space up to \(2^47\))
- Note: system provides private address spaces to each "process"
字长(Word Size):通常来说,可以表示该语言中一个指针的大小(地址的空间),或是表示某机器习惯处理的 x 位数值运算(比如 32 位,64 位)。不应该太过纠结于具体定义,我们常见过可以指定源代码编译时选择 64 位的还是 32 位的,字长不是完全的硬件特性,而是由硬件和编译器共同决定的。
课程是先讲的整数表示,运算,再讲这些和大小端的(一个多字节字中字节的存储顺序)。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!