12、經典問題解析一

一、關於const的疑問

const何時爲只讀變量,何時是常量

const常量的判別準則:c++

  • 只有用字面量初始化的cosnt常量纔會進入符號表
  • 使用其它變量初始化的const常量仍然是隻讀變量
  • voliatile修飾的cosnt常量不會進入符號表

在編譯期間不能直接肯定初始值的const標識符,都被做爲只讀變量處理編程

const引用的類型與初始化變量的類型數組

  • 相同:初始化變量成爲只讀變量
  • 不一樣:生成一個新的只讀變量
#include <stdio.h>

int main()
{
    const int x = 1;    // 字面量初始化,常量
    const int& rx = x;    // rx表明只讀變量,編譯器會爲常量x分配一個空間,可是不會被使用,經過別名rx後,可使用這個空間
    
    int& nrx = const_cast<int&>(rx); // 消除只讀變量的只讀屬性,nrx表明的空間和rx是同一段,只不過nrx沒有隻讀屬性,是一個普通變量
    
    nrx = 5;
    
    rx = 10;
    
    printf("x = %d\n", x);
    printf("rx = %d\n", rx);
    printf("nrx = %d\n", nrx);
    printf("&x = %p\n", &x);
    printf("&rx = %p\n", &rx);
    printf("&nrx = %p\n", &nrx);
    
    volatile const int y = 2;        // 用了volatile後,y就不是一個常量了,是一個只讀變量
    int* p = const_cast<int*>(&y);    // 指針指向y的內存空間
    
    *p = 6;
    
    printf("y = %d\n", y);
    printf("p = %p\n", p);        // 若是改變了y,則說明不是一個常量,沒有放進符號表中
    
    const int z = y;    // 這也是一個只讀變量
    
    p = const_cast<int*>(&z);
    
    *p = 7;
    
    printf("z = %d\n", z);
    printf("p = %p\n", p);
  
    // 不一樣類型的變量初始化const標識符
    char c = 'c';        
    char& rc = c;
    const int& trc = c;    // 用char型去初始化cosnt int&
    // 初始化類型不一樣的話,將獲得一個新的只讀變量
    
    rc = 'a';    // 改變rc和 trc就不要緊了

    printf("c = %c\n", c);
    printf("rc = %c\n", rc);
    printf("trc = %c\n", trc);
    
    return 0;
}

二、關於引用的疑問

引用與指針有什麼關係?如何理解「引用的本質就是指針常量」?

指針是一個變量:指針

  • 值爲一個內存地址,不須要初始化,能夠保存不一樣的地址
  • 經過指針能夠訪問對應內存地址中的值
  • 指針能夠被const修飾成爲常量或者只讀變量

引用只是一個變量的新名字:調試

  • 對引用的操做(賦值,取地址等)都會傳遞到表明的變量上
  • const引用使其表明的變量具備只讀屬性
  • 引用必須在定義時初始化,以後沒法表明其它變量

從使用C++語言的角度來看:code

  • 引用與指針沒有任何的關係
  • 引用是變量的新名字,操做引用就是操做對應的變量

從C++編譯器的角度來看內存

  • 爲了支持新概念「引用」必需要一個有效的解決方
  • 在編譯內部,使用指針常量來實現「引
  • 所以「引用」在定義時必須初始化

在工程項目開發中:開發

  • 當進行C++編程時,直接站在使用的角度看待引用,與指針毫無關係,引用就是變量的別名
  • 當對α++代碼進行調試分析時,一些特殊狀況,能夠考慮站在C++編譯器的角度看待引用
#include <stdio.h>

int a = 1;

struct SV
{
    int& x;
    int& y;
    int& z;
};

int main()
{
    int b = 2;
    int* pc = new int(3);
    SV sv = {a, b, *pc};     // 結構體裏面的每一個元素是一個引用 ok
    int& array[] = {a, b, *pc}; // &array[1] - &array[0] = ?  Expected ==> 4
    // 數組的每一個元素是引用,每一個元素的地址都是獨立的,並不連續,err
    // C語言有一個特性,數組地址連續,地址遞增
    // 引用數組會破壞這個特性,因此C++不支持引用數組
    
    printf("&sv.x = %p\n", &sv.x);
    printf("&sv.y = %p\n", &sv.y);
    printf("&sv.z = %p\n", &sv.z);
    
    delete pc;
    
    return 0;
}

三、小結

指針是一個變量

引用是一個變量的新名字編譯器

const引用可以生成新的只讀變量io

在編譯器內部使用指針常量實現「引用

編譯時不能直接肯定初始值的 const標識符都是隻讀變量

相關文章
相關標籤/搜索