内存区/类型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

进程的虚拟地址空间:
image

一个经典例子:

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节, 总结如下:

  1. 对单精度浮点数float, 有8位指数位和23位尾数位;
  2. 对双精度浮点数double, 有11位指数位和52位尾数位;
  3. 指数位的二进制表示成整数部分E, 尾数位的二进制表示成小数部分M;
  4. 考虑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成员函数或成员变量, 可直接通过类来调用/获取, 不需要先实例化一个类对象.
posted @ 2022-03-09 22:20  渐渐的笔记本  阅读(50)  评论(0编辑  收藏  举报