前言
前一篇文章我們主要介紹了C++中的復(fù)合類型引用和指針,這篇文章我們將會(huì)主要介紹C++中const關(guān)鍵字。有時(shí)候我們想定義一個(gè)值不能被改變的變量,例如我們想使用一個(gè)變量存儲(chǔ)buffer的大小,如果我們不希望這個(gè)值被改變,那么我們就可以使用const關(guān)鍵字。
const int bufSize = 512;
現(xiàn)在已經(jīng)定義了一個(gè)const變量bufSize,如果想對(duì)const變量賦值就會(huì)報(bào)錯(cuò)
bufSize = 256 //會(huì)報(bào)錯(cuò)
const初始化
因?yàn)樵谖覀儎?chuàng)建一個(gè)const對(duì)象后就沒有辦法改變const對(duì)象的值,所以其必須被初始化。
const int j = get_size(); //可以運(yùn)行時(shí)初始化
const int i = 42; //可以在編譯時(shí)初始化
const int k; //錯(cuò)誤,k沒有被初始化
正如之前我們多次提到的,一個(gè)對(duì)象的類型決定來其所有支持的操作,一個(gè)const類型可以使用絕大多數(shù)并不是全部非const類型的操作,唯一的限制就是我們使用的操作不能改變const對(duì)象的值,例如我們可以在算術(shù)表達(dá)式中將const類型的變量當(dāng)作非const類型的變量使用,因?yàn)槠錄]有改變const變量的值。
當(dāng)一個(gè)const對(duì)象在編譯期間就被一個(gè)常量初始化了,例如我們上述例子提到的bufSize在編譯期間就被初始化為512,在編譯期間編譯器就會(huì)將所有使用到bufSize的地方替換為512。為了替換變量的值,編譯器必須要知道變量的初始化結(jié)果,為了知道初始化結(jié)果,所有需要使用該變量的文件都需要定義該變量,為了支持這種用法,同時(shí)避免定義多個(gè)相同的變量,const變量對(duì)于文件來說是本地的,當(dāng)我們定義在不同的文件中定義多個(gè)同名的const變量,它們表現(xiàn)起來就像我們在不同的文件定義了不同的變量。
但是有時(shí)候我們希望在不同的文件中共享同一個(gè)const變量,但是其初始化并不是一個(gè)常量,我們并不希望編譯器為每一個(gè)文件生成單獨(dú)的變量,而是希望想非const變量一樣,我們希望在一個(gè)文件定義,然后在另一個(gè)文件聲明且使用該const變量,這時(shí)候就要使用extern關(guān)鍵字
//file1.cc定義切初始化了一個(gè)const變量
extern const int bufSize = fcn();
//file1.h
extern const int bufSize;
指向常量的引用
正如其他的對(duì)象,我們也可以將一個(gè)引用綁定到一個(gè)const類型的對(duì)象,為此我們可以使用一個(gè)引用指向,不同于一般的引用,一個(gè)指向常量的引用無法改變該引用指向的對(duì)象,這也很好理解,因?yàn)樵搶?duì)象是一個(gè)常量,而常量一旦定義就無法更改。
const int ci = 1024;
const int &r1 = ci; //正確,引用和引用指向的對(duì)象都是常量
r1 = 42; //錯(cuò)誤,r1指向的是一個(gè)常量,無法改變一個(gè)常量的值
int &r2 = ci; //錯(cuò)誤,無法讓一個(gè)非常量的引用指向一個(gè)常量
?一些開發(fā)這習(xí)慣于將指向常量的引用簡稱為常量引用,這個(gè)簡稱看上去說的通,但是你需要記住這就是個(gè)簡稱,從技術(shù)的角度來說是沒有常量引用的,因?yàn)橐粋€(gè)引用不是一個(gè)對(duì)象,所以我們無法讓一個(gè)引用本身是一個(gè)常量。
?
指向常量的引用未必指向一個(gè)常量
從之前的例子中我們可以看到指向一個(gè)常量的引用必須是一個(gè)常量引用,否則會(huì)報(bào)錯(cuò),但是一個(gè)指向常量的引用不一定指向一個(gè)常量,只是不同通過該引用來改變該對(duì)象的值,這么說可能有點(diǎn)繞,可以用以下例子說明
int i = 42;
int &r1 = i; //r1是指向i的引用
const int &r2 = i; //r2是指向i的常量引用,但是不能通過r2改變i的值
r1 = 0; //r1是非常量引用,可以通過r1改變i的值
r2 = 0; //r2是常量引用,無法通過r2改變i的值
指針與常量
與引用相同,指針可以指向常量也可以指向非常量,同樣指向常量的指針無法通過該指針來改變所指向的常量的值。
const double pi = 3.14; \\\\pi是一個(gè)常量,其值不可以改變
double *ptr = π //錯(cuò)誤 ptr不是一個(gè)指向常量的指針,所以無法指向pi
const double *cptr = π //正確,cptr是指向常量的指針
*cptr = 42; //錯(cuò)誤,cptr指向的是常量,其值無法改變
還是與引用相同,我們也可以讓一個(gè)指向常量的指針指向一個(gè)非常量,但是不可以通過該指針改變該對(duì)象的值
double dval = 3.14;
cptr = &dval; //正確,但是無法通過cptr改變dval的值
常量指針
與引用不同,指針本身是一個(gè)對(duì)象,所以其本身可以是常量,常量指針與其他的常量性質(zhì)是相同的,常量指針必須初始化,且一旦初始化該指針持有的地址也將不會(huì)改變,那么該如何聲明一個(gè)指針呢,那就是在*后加上const,例子如下
int errNumb = 0;
int *const curErr = &errNumb; //curErr是一個(gè)常量指針,將會(huì)一直指向errNumb
const double pi = 3.1425926;
const double *const pip = π //pip是一個(gè)常量指針且指向一個(gè)常量
常量表達(dá)式
常量表達(dá)式是指其返回值在編譯階段就能計(jì)算出來且不會(huì)改變的表達(dá)式,一個(gè)對(duì)象是否是常量表達(dá)式取決于其類型和初始化結(jié)果,例子如下
const int max_files = 20; //是
const int limit = max_files; //是
int staff_size = 27; //不是,因?yàn)槠漕愋筒皇莄onst
const int sz = get_size(); //不是,因?yàn)間et_size()需要在運(yùn)行時(shí)才能計(jì)算出來
constexpr
在一個(gè)大型的系統(tǒng)中有時(shí)候我們很難去確定初始化的結(jié)果是否是常量表達(dá)式,也許我們定義來一個(gè)常量并且用一個(gè)我們以為的常量表達(dá)式去初始化,但是一些場景下我們需要一個(gè)常量表達(dá)式但是最后返回不是一個(gè)常量表達(dá)式,那么一個(gè)對(duì)象在定義和使用的情況并不一致。在新標(biāo)準(zhǔn)下為了解決這個(gè)問題,提供了constexpr關(guān)鍵字,如果一個(gè)變量被constexpr修飾,那么編譯器將會(huì)檢查該變量是否是一個(gè)常量表達(dá)式。
constexpr int mf = 20; //20是常量表達(dá)式
constexpr int limit = mf + 1; //mf + 1是常量表達(dá)式
constexpr int sz = size(); //正確,如果size constexpr函數(shù),這個(gè)之后文章會(huì)介紹
指針與constexpr
需要注意的是如果我們定義一個(gè)指針在constexpr表達(dá)式中,那么constexpr是作用于指針,而不是指針指向的值。
const int *p = nullptr; //p是一個(gè)指向常量的指針
constexpr int *q = nullptr; //q是一個(gè)常量指針
constexpr const int *cptr = nullptr; //cptr是一個(gè)常量指針,且指向一個(gè)常量
-
buffer
+關(guān)注
關(guān)注
2文章
120瀏覽量
30533 -
C++
+關(guān)注
關(guān)注
22文章
2117瀏覽量
74861 -
CONST
+關(guān)注
關(guān)注
0文章
45瀏覽量
8417
發(fā)布評(píng)論請先 登錄
C++中常用關(guān)鍵字詳解(2)
DSP編程技巧之17---非?!?b class='flag-5'>關(guān)鍵”的關(guān)鍵字
C++筆記010:C++對(duì)C的擴(kuò)展——register關(guān)鍵字增強(qiáng)
嵌入式軟件編程中關(guān)鍵字的用法和原理
關(guān)鍵字static的作用是什么
嵌入式程序員常見的const、static、volatile關(guān)鍵字
C++語言基礎(chǔ)講解視頻標(biāo)識(shí)符與關(guān)鍵字
C++中的const和引用的討論
C++中mutable關(guān)鍵字詳解與實(shí)戰(zhàn)
淺談C++的mutable關(guān)鍵字
C語言|const關(guān)鍵字介紹
const關(guān)鍵字應(yīng)用總結(jié)
淺析C語言中的regiseter關(guān)鍵字

評(píng)論