C 语言基本类型在内存中的表示

C/C++不外乎以下几种基本类型:boolcharshortintlongfloatdouble,还有不常用的 long long

char 占用一个字节,而 short 占用两个字节,在 char 转化为 short 时,全部复制到 short 占用内存的低八位里面。

#include <iostream>

int main()
{
    char ch = 'A';
    short s = ch;
    std::cout << s << std::endl;
    return 0;
}
A 对应的 ASCII 码是 65,所以输出是 65。

反之,short 转化为 char 时,把高位的一个字节直接扔掉,只复制低字节。

short s = 67;
char ch = s;
std::cout << ch << std::endl;
输出是一个大写的 C。

int 一般占用 4 个字节,和 short 转化和上面 charshort 转化类似。下面看一个不太一样的例子。

int i = 1 << 15;
short s = i;
std::cout << s << std::endl;
i 在内存中的表示是 0000 0000, 0000 0000, 1000 0000, 0000 0000short 占用两个字节,直接把低位两个字节复制过来,s 在内存中的表示是 1000 0000, 0000 0000。第一位是符号位,表示负数,根据补码表示的意义,输出应该是负 2 的 15 次方,即 -32768。

float 也占用四个字节,但是每一位的含义不一样,第一位是符号位 s,接着的八位是 exp,接着 23 位是尾数,表示 0.dddfloat 的值等于 。 正常的 intfloat 很简单,比如:

int i = 5;
float f = i;
std::cout << f << std::endl;
就是正常的输出 5,只是 if 占用的内存对应的 bit 位上 0/1 差别很大。

来看个不正常的转化

int i = (1 << 22) + (1 << 30);
float f = * (float*) &i;
std::cout << f << std::endl;
i 在内存中的表示是 0100 0000, 0100 0000, 0000 0000, 0000 0000f 的赋值使用了 i 的内存,以 float 的方式去读。符号位是 0,表示正数,exp 是 1000 0000,也就是128,再后面是一个 1,22 个 0,尾数就是 1.1。所以 f 等于 ,即输出 3。注意,这个等式第一步把二进制变成了十进制。