靈活而奇特的C 語言特性 const(一)

2021-07-25 01:52:29 字數 3553 閱讀 4307

學習了博主的《漫談繼承技術》系列博文之後,相信大家都有所收穫吧!這次博主將和大家一起** 《靈活而奇特的c++語言特性》 ,主要包括引用、常量(const)、常量表示式(constexpr)、靜態(static)、外部(expert)、型別定義(typedef)、型別別名(aliases)、型別轉換、作用域解析、統一初始化、顯示轉換運算子、特性(attribute)、使用者自定義文字、標頭檔案、可變長度引數列表和預處理器巨集。儘管這個知識清單顯得有點凌亂,但是這些話題都是博主經過精心挑選,是容易混淆的語言特性。本篇我們來學習一下const,增進大家對《靈活而奇特的c++語言特性》的理解。

const是constant的縮寫,指保持不變的量。編譯器會執行這一要求,任何嘗試改變常量的行為都會當作錯誤處理。此外,當啟用了優化時,編譯器可以利用此資訊生成更好的**。關鍵字const主要有兩種相關的用法。可以用這個關鍵字標記變數或者引數,也可以用const標記方法。本篇博文主要**const變數和引數的含義,希望對大家有一點幫助。

在使用const之前,讓我們先來了解一下const的特性:

①const常量,在定義時必須初始化。

②const常量,在編譯的過程中將該常量替換為初始化時的值。

③可以通過強制型別轉換將常量的位址賦給指標變數,通過指標變數來修改所指向的空間裡的值。

咱們舉個栗子吧:

#include

using

namespacestd;

int main(int

argc,char**argv)

程式執行結果:

注意,上面的特性要視具體的編譯器而定,以上是我在vs 2013上的測試結果。我在圖釋中所說的整型包括bool、char、short、int和long型等資料型別。

如果將上面**中的「constint size;」解注釋,編譯器將會報以下錯誤:

可能有的小夥伴會問:「c語言中的const和c++中的const有什麼不同,為什麼有的時候我將c++中編譯通過的**放到c原始檔中就會出現編譯錯誤?」。善於發現問題,說明你已經比別人強很多。其實,c語言中const定義的是唯讀變數,不是真正意義上的常量,c++中const定義的才是真正意義上的常量。那什麼是真正意義上的常量呢?下面我們一起來揭秘一下吧。

#define

_crt_secure_no_warnings

//關閉安全性檢測

#include

using

namespacestd;

enum

color;

int main(int

argc,char**argv)

;//在c

原始檔中次行語句報錯

inti = 0;

//初始化陣列

for(auto&var : narray)

//輸出陣列所有元素

cout<< "narray =

cout<< "}"

<< endl;

//switch

的引數必須要是整型常量

switch(size)//在c

中次行語句報錯

return0; }

程式執行結果:

在c語言中,const修飾的是唯讀變數,其實它本質還是變數,在真正需要使用常量的地方都會報語法錯誤。而c++中對const進行了擴充,使其修飾的是真正意義上的常量。

可以使用const來「保護」變數不被修改。這個關鍵字的乙個重要用法是替換define來定義常量,這是const最直接的應用。上面程式中已經舉過栗子啦,這裡就不在贅述。可能有的小夥伴會問:「那const和define到底有什麼區別呢?還是只是提供了一種新的定義常量的方式而已?」。當然不是啦,const比define更實用更安全,接下來就讓我們一起來**const和define之間的區別吧。

const和define之間的主要區別:

①define定義的常量在預處理時進行替換,const定義的常量在編譯的過程中進行替換

②define只是進行簡單的字元替換,不進行型別檢查,const則進行型別檢查

③define定義的常量不會分配空間,而const則會分配空間

④define定義的常量不支援除錯(不能檢視它在記憶體空間裡的值),而const定義的常量則可以。

⑤define不能定義形參,const則可以定義形參

const修飾變數,這個變數包括指標變數。可能有的小夥伴聽說過指標常量和常量指標的概念,並對此十分困惑,總是搞混。沒關係,初學指標碰點壁也是很正常的。接下來我們就一起來聊聊它們之間的差異吧。

#include

using

namespacestd;

int main(int

argc,char**argv)

程式執行結果:

上述**中「const

int*nptr = &nvalue1;」也可以寫成「intconst *nptr = &nvalue1;」,其效果是一樣的。然而,這一規則卻不適應與「int* const ncptr = &nvalue2;」,將該語句寫為「int* ncptr const = &nvalue2;」或「int

const* ncptr = &nvalue2;」則不行,直接改變了語句,甚至無法通過編譯。

可以嘗試著從右向左讀,「int* const ncptr = &nvalue2;」,const與ncptr現結合,就知道ncptr是乙個指向int的const指標。另一方面,「int const*nptr = &nvalue1;」,「*」先和nptr結合,就知道nptr是乙個指向const int的指標。

const可以應用於引用,它通過比應用於指標更簡單。一是,引用預設為const,無法改變引用所指的物件。因此,無法顯式地將引用標記為const。二是,無法建立乙個引用的引用,所以引用通過只有一層間接取值。獲取多層間接取值的唯一方法是建立指標的引用。舉個栗子:

const

int* const * const* const * constptr = nullptr;

const

int* const * const* const * const&ref = ptr;

將物件作為引數傳遞時,預設選擇是const引用。只有在明確需要修改物件時,才能忽略const。const修飾函式引數的的場景我們已經見過,例如拷貝建構函式,構造函式引數等。這裡就不舉栗子了,如果你確實想看栗子的話,就去《靈活而奇特的c++語言特性——引用(下)》,那裡有乙個封裝mystring類的栗子。

靈活而奇特的C 語言特性 引用(上)

學習了博主的 漫談繼承技術 系列博文之後,相信大家都有所收穫吧!這次博主將和大家一起 靈活而奇特的c 語言特性 主要包括引用 常量 const 常量表示式 constexpr 靜態 static 外部 expert 型別定義 typedef 型別別名 aliases 型別轉換 作用域解析 統一初始化...

靈活而奇特的C 語言特性 const(二)

學習了博主的 漫談繼承技術 系列博文之後,相信大家都有所收穫吧!這次博主將和大家一起 靈活而奇特的c 語言特性 主要包括引用 常量 const 常量表示式 constexpr 靜態 static 外部 expert 型別定義 typedef 型別別名 aliases 型別轉換 作用域解析 統一初始化...

靈活而奇特的C 語言特性 作用域解析(二)

學習了博主的 漫談繼承技術 系列博文之後,相信大家都有所收穫吧!這次博主將和大家一起 靈活而奇特的c 語言特性 主要包括引用 常量 const 常量表示式 constexpr 靜態 static 外部 expert 型別定義 typedef 型別別名 aliases 型別轉換 作用域解析 統一初始化...