那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C++中的const關鍵字介紹

jf_78858299 ? 來源:QStack ? 作者: 月下西樓 ? 2023-03-17 14:01 ? 次閱讀

前言

前一篇文章我們主要介紹了C++中的復合類型引用和指針,這篇文章我們將會主要介紹C++中const關鍵字。有時候我們想定義一個值不能被改變的變量,例如我們想使用一個變量存儲buffer的大小,如果我們不希望這個值被改變,那么我們就可以使用const關鍵字。

const int bufSize = 512;

現在已經定義了一個const變量bufSize,如果想對const變量賦值就會報錯

bufSize = 256 //會報錯

const初始化

因為在我們創建一個const對象后就沒有辦法改變const對象的值,所以其必須被初始化。

const int j = get_size(); //可以運行時初始化
const int i = 42//可以在編譯時初始化
const int k; //錯誤,k沒有被初始化

正如之前我們多次提到的,一個對象的類型決定來其所有支持的操作,一個const類型可以使用絕大多數并不是全部非const類型的操作,唯一的限制就是我們使用的操作不能改變const對象的值,例如我們可以在算術表達式中將const類型的變量當作非const類型的變量使用,因為其沒有改變const變量的值。

當一個const對象在編譯期間就被一個常量初始化了,例如我們上述例子提到的bufSize在編譯期間就被初始化為512,在編譯期間編譯器就會將所有使用到bufSize的地方替換為512。為了替換變量的值,編譯器必須要知道變量的初始化結果,為了知道初始化結果,所有需要使用該變量的文件都需要定義該變量,為了支持這種用法,同時避免定義多個相同的變量,const變量對于文件來說是本地的,當我們定義在不同的文件中定義多個同名的const變量,它們表現起來就像我們在不同的文件定義了不同的變量。

但是有時候我們希望在不同的文件中共享同一個const變量,但是其初始化并不是一個常量,我們并不希望編譯器為每一個文件生成單獨的變量,而是希望想非const變量一樣,我們希望在一個文件定義,然后在另一個文件聲明且使用該const變量,這時候就要使用extern關鍵字

//file1.cc定義切初始化了一個const變量
extern const int bufSize = fcn();

//file1.h
extern const int bufSize;

指向常量的引用

正如其他的對象,我們也可以將一個引用綁定到一個const類型的對象,為此我們可以使用一個引用指向,不同于一般的引用,一個指向常量的引用無法改變該引用指向的對象,這也很好理解,因為該對象是一個常量,而常量一旦定義就無法更改。

const int ci = 1024;
const int &r1 = ci; //正確,引用和引用指向的對象都是常量
r1 = 42; //錯誤,r1指向的是一個常量,無法改變一個常量的值
int &r2 = ci; //錯誤,無法讓一個非常量的引用指向一個常量

?一些開發這習慣于將指向常量的引用簡稱為常量引用,這個簡稱看上去說的通,但是你需要記住這就是個簡稱,從技術的角度來說是沒有常量引用的,因為一個引用不是一個對象,所以我們無法讓一個引用本身是一個常量。

?

指向常量的引用未必指向一個常量

從之前的例子中我們可以看到指向一個常量的引用必須是一個常量引用,否則會報錯,但是一個指向常量的引用不一定指向一個常量,只是不同通過該引用來改變該對象的值,這么說可能有點繞,可以用以下例子說明

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是一個常量,其值不可以改變
double *ptr = π //錯誤 ptr不是一個指向常量的指針,所以無法指向pi
const double *cptr = π //正確,cptr是指向常量的指針
*cptr = 42; //錯誤,cptr指向的是常量,其值無法改變

還是與引用相同,我們也可以讓一個指向常量的指針指向一個非常量,但是不可以通過該指針改變該對象的值

double dval = 3.14;
cptr = &dval; //正確,但是無法通過cptr改變dval的值

常量指針

與引用不同,指針本身是一個對象,所以其本身可以是常量,常量指針與其他的常量性質是相同的,常量指針必須初始化,且一旦初始化該指針持有的地址也將不會改變,那么該如何聲明一個指針呢,那就是在*后加上const,例子如下

int errNumb = 0;
int *const curErr = &errNumb; //curErr是一個常量指針,將會一直指向errNumb
const double pi = 3.1425926;
const double *const pip = π //pip是一個常量指針且指向一個常量

常量表達式

常量表達式是指其返回值在編譯階段就能計算出來且不會改變的表達式,一個對象是否是常量表達式取決于其類型和初始化結果,例子如下

const int max_files = 20; //是
const int limit = max_files; //是
int staff_size = 27; //不是,因為其類型不是const
const int sz = get_size(); //不是,因為get_size()需要在運行時才能計算出來

constexpr

在一個大型的系統中有時候我們很難去確定初始化的結果是否是常量表達式,也許我們定義來一個常量并且用一個我們以為的常量表達式去初始化,但是一些場景下我們需要一個常量表達式但是最后返回不是一個常量表達式,那么一個對象在定義和使用的情況并不一致。在新標準下為了解決這個問題,提供了constexpr關鍵字,如果一個變量被constexpr修飾,那么編譯器將會檢查該變量是否是一個常量表達式。

constexpr int mf = 20; //20是常量表達式
constexpr int limit = mf + 1; //mf + 1是常量表達式
constexpr int sz = size(); //正確,如果size constexpr函數,這個之后文章會介紹

指針與constexpr

需要注意的是如果我們定義一個指針在constexpr表達式中,那么constexpr是作用于指針,而不是指針指向的值。

const int *p = nullptr; //p是一個指向常量的指針
constexpr int *q = nullptr; //q是一個常量指針
constexpr const int *cptr = nullptr; //cptr是一個常量指針,且指向一個常量
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • buffer
    +關注

    關注

    2

    文章

    120

    瀏覽量

    30130
  • C++
    C++
    +關注

    關注

    22

    文章

    2114

    瀏覽量

    73857
  • CONST
    +關注

    關注

    0

    文章

    45

    瀏覽量

    8187
收藏 人收藏

    評論

    相關推薦

    C語言關鍵字const的幾種用法

    本期來講解一個C語言的關鍵字——const
    發表于 06-21 11:05 ?1717次閱讀
    <b class='flag-5'>C</b>語言<b class='flag-5'>關鍵字</b><b class='flag-5'>const</b>的幾種用法

    C++中常用關鍵字詳解(2)

    C++,volatile是一個關鍵字,用于修飾變量,告訴編譯器該變量的值可能在程序流程之外被意外修改,因此編譯器不應該對該變量進行優化(如緩存變量值或重排指令順序)。
    發表于 08-08 16:15 ?377次閱讀

    DSP編程技巧之17---非常“關鍵”的關鍵字

      使用cregister關鍵字,當我們定義的該類型的對象與C28x的標準的控制寄存器匹配時,編譯器會自動產生相關的代碼去控制對應的寄存器,使得我們可以在高級編程語言C/C++
    發表于 08-20 11:38

    C++筆記010:C++C的擴展——register關鍵字增強

    的地址在C語言里面是會出錯的。同樣的代碼我們放到C++編譯環境下,發現編譯是通過的!在C++依然支持register關鍵字
    發表于 08-11 12:34

    嵌入式軟件編程關鍵字的用法和原理

    ,但是某些關鍵字,例如const、static、extern和volatile等,在不同的場合具有不同的含義,而且某些用法晦澀難懂,為此本文詳細介紹這些關鍵字的用法及其背后的原理。
    發表于 06-20 07:37

    關鍵字static的作用是什么

    嵌入式面經1.關鍵字static的作用是什么2.關鍵字const是什么含意?3.const和宏定義的區別4.關鍵字volatile有什么含意
    發表于 11-09 07:23

    嵌入式程序員常見的const、static、volatile關鍵字

    嵌入式程序員const、static、volatile三個關鍵字的樸素認識摘要:在C語言程序編寫const、static
    發表于 12-21 06:08

    C++語言基礎講解視頻標識符與關鍵字

    C++語言基礎講解視頻標識符與關鍵字,喜歡的朋友可以下載來學習。
    發表于 01-14 15:31 ?7次下載

    C++Cconst關鍵字有何差別?

    C++Cconst關鍵字有何差別?
    的頭像 發表于 02-03 14:51 ?1856次閱讀

    C++const和引用的討論

    今天給大家分享一下這段時間學習c++的總結學習:c++里面的const關鍵字和引用。
    的頭像 發表于 12-24 15:35 ?889次閱讀

    C++mutable關鍵字詳解與實戰

    mutable關鍵字詳解與實戰 在C++mutable關鍵字是為了突破const關鍵字的限制,
    的頭像 發表于 09-10 09:23 ?5597次閱讀

    淺談C++的mutable關鍵字

    C++11推出了一種特殊的關鍵字:mutable用于修飾類變量。它的作用是標注該變量一定會被修改,因此也就不是const類型。目的是為了使這些成員變量在被
    的頭像 發表于 04-15 11:13 ?3851次閱讀

    C語言|const關鍵字介紹

    最近看別人的項目, 發現const使用比較多, 通過使用const來保護變量, 這篇推文就來簡單回顧一下相關知識!
    的頭像 發表于 05-25 15:11 ?572次閱讀

    const關鍵字應用總結

    C++const關鍵字的用法非常靈活,而使用const將大大改善程序的健壯性
    的頭像 發表于 05-26 09:06 ?614次閱讀

    淺析C語言中的regiseter關鍵字

    C語言中重要的關鍵字有很多,static const extern我們之前都講過,還有一個在面試中出現的頻率也比較高:register。
    的頭像 發表于 08-25 17:10 ?1173次閱讀
    淺析<b class='flag-5'>C</b>語言中的regiseter<b class='flag-5'>關鍵字</b>
    叶氏百家乐平注技巧| 基础百家乐官网博牌规| 百家乐视频二人麻将| 百家乐百战百胜| 香港六合彩总公司| ewin娱乐城官方下载| 电脑版百家乐官网下注技巧| 百家乐官网怎样玩才会赢钱| 百家乐画面方法| 法库县| 立博百家乐官网的玩法技巧和规则| 百家乐园云顶娱乐主页| 德州扑克发牌视频| 百家乐官网投注庄闲法| 百家乐牌机的破解法| 大发888网址是多少| 百家乐官网天下第一庄| 百家乐技巧微笑心法| 蒙特卡罗娱乐场| 百家乐官网娱乐城提款| 百家乐体育nba| 利澳娱乐城注册| 真人百家乐官网赌注| 百家乐娱乐网备用网址| 百家乐官网靠什么赢| 百家乐娱乐全讯网| 丰禾娱乐城开户| 百家乐官网牌九| 大发888赌博网站大全| 澳门百家乐官网公试打法| 百家乐视频游戏世界| 足球竞猜| 新乐园百家乐官网娱乐城| 大发888官方授权网| 什么是百家乐官网的大路| 全讯网zq06| 百家乐官网娱乐平台真人娱乐平台| 九州百家乐的玩法技巧和规则| 澳门百家乐官网娱乐城打不开| 百家乐龙虎玩| 六合彩开奖结果直播|