作者:李春港
出處:https://www.cnblogs.com/lcgbk/p/14502076.html
一、前言
在c++中什麼情況下,當我們定義一個常量時,編譯器都做了哪些操作呢?首先讓我們看下一節的程式。
二、程式碼例項
#include<iostream>
using namespace std;
int main ()
{
int const tmp = 100; //定義常量tmp tmp不能修改
int const* p = &tmp; //不能通過指標修改指向的值
int* const q = const_cast<int*>(p); //去常屬性 可以通過指標修改指向的內容
*q = 200;
cout << tmp << " " << *p << " " << *q << endl; //列印變數的值
cout << &tmp << endl << p << endl << q << endl; //列印變數地址
return 0;
}
看了以上程式你覺得結果會是怎麼樣呢?
結果:
100
200
200
00556820
00556820
00556820
到這裡你會發現:為什麼怎麼地址一樣,但值卻不一樣呢?
我們就相當於和編譯器約定好了,我們不會去修改 tmp 的值,這個時候編譯器就會做一個優化,將 tmp 的值,放到暫存器裡面,然後讀取 tmp 時直接在暫存器裡面讀取,加快讀取速度。
所以出現以上情況是因為:tmp 讀取的是「暫存器」的值,p ,q讀取的是「記憶體」的值。
三、volatile作用
以上例項出現的情況,有時候我們並不希望這樣的情況出現,然而 volatile 可以為我們去除這樣的優化,使用該關鍵字,相當於告訴編譯器,這個關鍵字修飾的變數要到記憶體裡面去操作,不要直接從暫存器取值。
優化程式碼如下:
volatile int const tmp2 = 100;
volatile int const* pm = &tmp2; //不能通過指標修改指向的值
int* const qm = const_cast<int*>(pm); //q本身只讀 指向讀寫
*qm = 200;
cout << tmp2 << " " << *pm << " " << *qm << endl;
cout << (void*)&tmp2 << endl << (void*)pm << endl << qm << endl;
列印結果:
200
200
200
00666820
00666820
00666820
這樣就不會出現地址一樣,數值不一樣的情況了,也是我們希望看到的結果。