内存区/类型cast/static@C++
1 C++ 内存分区
- 栈区(stack)
- 堆区(heap)
- 代码区(.text[read-only for program])
- 常量区(.rodata[read-only for constant])
- 全局(静态)存储区
- .data: initialized / read & write
- .bss: uninitialized / read & write
进程的虚拟地址空间:
一个经典例子:
int a = 0; //全局初始化区
char *p; //全局未初始化区
void main()
{
int b; //栈区
char s[] = "abcd"; //栈区
char *p2; //栈区
char *p3 = "123456"; //123456在常量区,p3在栈区
static int c = 0; //全局(静态)初始化区
p1 = (char *)malloc(10); //分配所得的10字节区域位于堆区
p2 = (char *)malloc(20); //分配所得的20字节区域位于堆区
strcpy(p1, "123456");
}
2 四种显示类型转换算子
- static_cast<>
需要进行类型转换时, 首先考虑使用static_cast;
可以将右值转换成右值引用static_cast<int&&>(7); - reinterpret_cast<>
最危险的一种cast,应该尽可能地少用。
关于static_cast和reintepret_cast的一个例子:
#include <iostream>
#include <vector>
using namespace std;
int main() {
int a = 10;
float b =10.01;
int* pi = &a;
float* pf = &b;
// float* pitof = static_cast<float*>(pi); 这里使用static_cast会报错
float* pitof = reinterpret_cast<float*>(pi);
cout << *pi << endl;
cout << *pf << endl;
cout << *pitof << endl;
return 0;
}
输出的结果如下:
10
10.01
1.4013e-44
1.4013e-44
是怎么来的呢, 它是将二进制(000...1010)
解释成了浮点数。对浮点数的理解, 可以阅读《CSAPP》的2.4节, 总结如下:
- 对单精度浮点数float, 有8位指数位和23位尾数位;
- 对双精度浮点数double, 有11位指数位和52位尾数位;
- 指数位的二进制表示成整数部分
E
, 尾数位的二进制表示成小数部分M
; - 考虑float, 可以分以下3种情况
E==0
(指数位全是0): 表示的浮点数的值为\(float = (-1)^s\times M\times 2^{-126}\), 所以浮点数的+0
的二进制全是0,-0
除了符号位其它都是0;E==127
(指数位全是1): 如果尾数位全是0, 表示+∞
和-∞
; 如果尾数不是全为0, 表示NaN
(Not a Number);- 指数位有0有1: \(float = (-1)^s \times (1+M) \times 2^{E-127}\), 在这种情况下\(E \in [1, 254]\)。
- const_cast<>
const_cast不会进行类型转换, 不过它可以给变量添加或去除const
属性
void aFunction(int* a)
{
cout << *a << endl;
}
int main()
{
int a = 10;
const int* iVariable = &a;
aFunction(const_cast<int*>(iVariable));
/*Since the function designer did not specify the parameter as const int*, we can strip the const-ness of the pointer iVariable to pass it into the function.
Make sure that the function will not modify the value. */
return 0;
}
- dynamic_cast<>
参考资料:
1 C++ casting
2 When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?
3 C++:18---强制类型转换(static_cast、const_cast、dynamic_cast、reinterpret_cast)
3 static关键字
- static修饰的变量位于内存的全局/静态存储区, 程序退出才移出内存;
- 类中的static成员函数或成员变量, 可直接通过类来调用/获取, 不需要先实例化一个类对象.