计算机使用字节(byte)块来储存数据。实际情况中,一般是使用使用DRAM,硬盘等硬件以及操作系统及逆行结合,最终使得程序能够以字节的形式展现。实际情况中,例如C中的指针都是一个虚拟地址,而C编译器则会根据具体类型来生成机器码,使得每一个指针能够访问到储存其中数据的部分。
2.1.1 十六进制表示法
一个字节能够表示$00000000_2-11111111_2$,对于十进制(无符号整数)其则是$0-255$,而对于十六进制其则是$00_{16}-FF_{16}$。一般来说对于十六进制的表示会在前面加上0x,如$FA1D37B_{16}$则会表示为$0xFA1D37B$。
进制的转换比较简单,跑来看这个的应该没有人不会吧(
2.1.2 数据大小
在每个计算机中都有一个word size,正常来讲其表示一个指针的大小。一般这个word size还同样表示虚存中最大的地址空间。如果一个计算机的word size是$\omega$,则其虚存的地址能从0到$2^{\omega}-1$,也就是一共又$2^{\omega}$字节。32位计算机最多能够使用的内存有$4\times 10^9$字节,而64位计算机最多有$1.84\times 10^{19}$字节。
在C语言中,当采用不同位的系统的时候,不同的类型有时对应的大小也不一样,如上图。
2.1.3 地址顺序
对于不同的操作系统或者硬件,有时其储存数据的方式也不一样。最常见的两种方式包括Big Endian以及Little Endian。
对于一个十进制数0x01234567,在一个32位的整数类型中:
big endian的储存顺序是01 23 45 67,相当于最高位的数储存在前面。
little endian的储存顺序则是67 45 23 01,相当于最低位的数储存在前面。
Intel处理器大多是采用Little Endian,而IBM以及Sun则采用Big Endian。而ARM处理器既可以工作在Big Endian,也可以工作在Little Endian模式。不过IOS和Android系统都是使用后者。
2.1.4 字符串的表示
C中的字符串是一串以null为结尾的字符。每一个字符都对应这一个ASCII码。如字符串12345则对应31 32 33 34 35 00(最后一个null为0x00)。
2.1.5 机器码
拥有不同指令集的处理器,对于同样一段程序,编译出来的机器码一般不一样。而对于不同的操作系统,编译得到的结果有可能也会有所不同,这实际上取决于编译器。
2.1.6-2.1.8 位运算以及逻辑运算
与,&:两个位均为1时返回1
或,|:两位至少有一个为1时返回1
异或,^:两位相同为0,不同为1
非,~:~0=1,~1=0
逻辑运算:有&&,||,!三种形式。其中&&则是如果进行运算的两个数都不为0,则返回1,||时两个数不同时为0,返回1,而!0=1,!x(x!=0)=0
2.1.9 二进制的移位运算:
左移没有区别,都是转换为二进制后面直接补充0,然后前面溢出的数全部舍去,如11111111b << 5 = 11100000b,而右移则分为算术以及逻辑运算,其中逻辑右移是直接在二进制数的左边直接补充0,而算术右移则是使用二进制数的最高一位数进行代替,如11000000b >> 5 = 11111110b,01100000b >> 3 = 00001100b,其中,当无符号数进行右移的时候执行的是逻辑右移,而带符号数执行的是算术右移。
在32位的C程序中,long是4字节,而64位的程序中,long是8字节