c++整型提升的规则: memory中存储的是补码,是根据存入的具体数据的值进行转换的二进制的形式。 类型提升/截断的时候都是对内存中的数据的操作, 提升就是进行扩位:对于无符号数,就是直接把扩出的位补0;对于有符号数,则需要进行符号位扩展,如果是正数即最高位是0则补0,如果是负数即最高位是1则全补1。 截断是从低位开始数位数然后截断。 char -2^7~+2^7-1 1byte unsigned char 0~+2^8-1 1byte short int -2^15~2^15-1 2bytes unsigned short int 0~2^16-1 2bytes int/long -2^31~2^31-1 4bytes unsigned int/sunsigned long 0~2^32-1 4bytes long long -2^63~2^63-1 8bytes unsigned long long 0~2^64-1 8bytes float 4bytes double 8bytes long double 表示的数值范围与double一样(不确定),确切精度取决于编译器。 浮点参数压栈的规则:float(4字节)类型扩展成double(8字节)入栈。
注意:我们使用的一般是小端机(little Endian,在内存中,低字节在前,eg:0x1234,在内存中表示为34 12)。
内存分配&重新分配: 对于vector和string,如果需要更多的空间,会以realloc的思想来增长大小。 realloc: 1.分配新的内存块,分配的大小一般为当前容器内存的数倍。在大部分实现中,vector和string的容量大小以2的倍数增长。即,当容器必须扩展时,它们的容量每次翻倍。 2.把所有元素从容器的旧内存拷贝到它的新内存。 3.析构旧内存中的对象。 4.释放旧内存
不仅如此,当需要更大的空间时,每次添加新的元素,还需要重新更新指向vector和string的迭代器、指针和引用。
reserve成员函数能够使重新分配的次数减少到最低限度,从而避免重新分配,和指针、迭代器引用失效带来的开销。
vector<int> v; v.reserve(1000); for(int i=0;i<=1000;i++) v.push_back(i);capacity()返回的是当前vector对象缓冲区实际申请的空间大小,而size()返回的是当前对象缓冲区中存储数据的个数,capacity永远是大于等于size的,当size和capacity相等时继续添加数据时vector会扩容。