volatile、const的用法

1. volatile

  • 訪問寄存器要比訪問內存要塊,因此CPU會優先訪問該數據在寄存器中的存儲結果,但是內存中的數據可能已經發生了改變,而寄存器中還保留著原來的結果。為了避免這種情況的發生將該變量聲明為volatile,告訴CPU每次都從內存去讀取數據。
  • 防止編譯器對變量的優化
  • 一個參數可以即是const又是volatile的嗎? 答案:可以

?

2. const

一、const作用

???如下表所示:

No.

作用

說明

參考代碼

1

可以定義const常量

 

const int Max = 100;?

2

便于進行類型檢查

const常量有數據類型,而宏常量沒有數據類型。編譯器可以對前者進行類型安全檢查,而對后者只進行字符替換,沒有類型安全檢查,并且在字符替換時可能會產生意料不到的錯誤

void f(const int i) { .........}
??????//對傳入的參數進行類型檢查,不匹配進行提示

3

可以保護被修飾的東西

防止意外的修改,增強程序的健壯性。

void f(const int i) { i=10;//error! }
??????//如果在函數體內修改了i,編譯器就會報錯

4

可以很方便地進行參數的調整和修改

同宏定義一樣,可以做到不變則已,一變都變

 

5

為函數重載提供了一個參考

 

class A
{
???????????......
??void f(int i)???????{......}?//一個函數
??void f(int i) const {......}?//上一個函數的重載
???????????......
};

6

可以節省空間,避免不必要的內存分配

const定義常量從匯編的角度來看,只是給出了對應的內存地址,而不是象#define一樣給出的是立即數,所以,const定義的常量在程序運行過程中只有一份拷貝,而#define定義的常量在內存中有若干個拷貝

#define PI 3.14159?????????//常量宏
const doulbe??Pi=3.14159;??//此時并未將Pi放入ROM中
??????????????......
double i=Pi;???//此時為Pi分配內存,以后不再分配!
double I=PI;??//編譯期間進行宏替換,分配內存
double j=Pi;??//沒有內存分配
double J=PI;??//再進行宏替換,又一次分配內存!

7

?提高了效率

編譯器通常不為普通const常量分配存儲空間,而是將它們保存在符號表中,這使得它成為一個編譯期間的常量,沒有了存儲與讀內存的操作,使得它的效率也很高

 

?

?

?

二、Const的使用

1、定義常量:?const修飾變量,以下兩種定義形式在本質上是一樣的。它的含義是:const修飾的類型為TYPE的變量value是不可變的。

TYPE const ValueName = value; 
const TYPE ValueName = value;

2、指針使用const

  • (1).指針本身是常量不可變: char* const pContent;?
  • (2).指針所指向的內容是常量不可變:?const char *pContent;?
  • (3).兩者都不可變:const char* const pContent;?

還有其中區別方法,沿著*號劃一條線:

  • 如果const位于*的左側,則const就是用來修飾指針所指向的變量,即指針指向的對象為常量;
  • 如果const位于*的右側,const就是修飾指針本身,即指針本身是常量。

?

3、函數中使用const

(1). const修飾函數參數

  • 傳遞過來的參數在函數內不可以改變(無意義,因為Var本身就是形參)
void function(const int Var);
  • 參數指針所指內容為常量不可變。
void function(const char* Var);
  • 參數指針本身為常量不可變(也無意義,因為char* Var也是形參)
void function(char* const Var);
  • 參數為引用,為了增加效率同時防止修改。修飾引用參數時:
void function(const Class& Var);?// 引用參數在函數內不可以改變
void function(const TYPE& Var);? // 引用參數在函數內為常量不可變

這樣的一個const引用傳遞和最普通的函數按值傳遞的效果是一模一樣的,他禁止對引用的對象的一切修改,唯一不同的是按值傳遞會先建立一個類對象的副本,?然后傳遞過去, 而它直接傳遞地址,所以這種傳遞比按值傳遞更有效.另外只有引用的const傳遞可以傳遞一個臨時對象,因為臨時對象都是const屬性,?且是不可見的,他短時間存在一個局部域中,所以不能使用指針,只有引用的const傳遞能夠捕捉到這個家伙。


(2). const?修飾函數返回值
const修飾函數返回值其實用的并不是很多,它的含義和const修飾普通變量以及指針的含義基本相同。

const int fun1()?   //這個其實無意義,因為參數返回本身就是賦值。const int* fun2()?  // 調用時?const int *pValue = fun2();?                        // 我們可以把fun2()看作成一個變量,即指針z指向的對象不可變。int* const fun3()? //調用時?int * const pValue = fun2();?//我們可以把fun2()看作成一個變量,即指針本身不可變。

一般情況下,函數的返回值為某個對象時,如果將其聲明為const時,多用于操作符的重載。通常,不建議用const修飾函數的返回值類型為某個對象或對某個對象引用的情況。原因如下:如果返回值為某個對象為const(const A test = A?實例)或某個對象的引用為const(const A& test = A實例) ,則返回值具有const屬性,則返回實例只能訪問類A中的公有(保護)數據成員和const成員函數,并且不允許對其進行賦值操作,這在一般情況下很少用到。


4、類相關const

(1). const修飾成員變量:const修飾類的成員函數,表示成員常量,不能被修改,同時它只能在初始化列表中賦值。

class A
{const int nValue; ? ? ? ??//成員常量不能被修改A(int x) : nValue(x) { };?//只能在初始化列表中賦值
};


(2). const修飾類成員函數:const成員函數表示該成員函數不能修改類對象中的任何非const成員變量。一般const寫在函數的后面,形如:void func() const;如果某個成員函數不會修改成員變量,那么最好將其聲明為const,因為const成員函數不會對數據進行修改,如果修改,編譯器將會報錯;

class A {void function() const;?// 常成員函數,?它不改變對象的成員變量.????????????????????????// 也不能調用類中任何非const成員函數。
}

※ mutable關鍵字:

在C++中,mutable是為了突破const的限制而設置的。被mutable修飾的變量,將永遠處于可變的狀態,即使在一個const函數中,甚至結構體變量或者類對象為const,其mutable成員也可以被修改:

class ST {
public:int a;mutable int showCount;void Show()const;
};void ST::Show()const
{//a=1; //錯誤,不能在const成員函數中修改普通變量 showCount++;//正確 
}

?

3. const修飾類對象/對象指針/對象引用

  • const修飾類對象表示該對象為常量對象,其中的任何成員都不能被修改。對于對象指針和對象引用也是一樣。
  • const修飾的對象,該對象的任何非const成員函數都不能被調用,因為任何非const成員函數會有修改成員變量的企圖。
    例如:
class AAA
{void func1();void func2() const;
};int main()
{const AAA aObj;aObj.func1();?//×aObj.func2();?//正確const AAA* aObj = new AAA();aObj->func1();?// ×aObj->func2();?// 正確
}

?

參考資料:

  • 關于C++ const 的全面總結《轉》

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/385227.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385227.shtml
英文地址,請注明出處:http://en.pswp.cn/news/385227.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

1030 完美數列 (25 分)

給定一個正整數數列,和正整數 p,設這個數列中的最大值是 M,最小值是 m,如果 M≤mp,則稱這個數列是完美數列。 現在給定參數 p 和一些正整數,請你從中選擇盡可能多的數構成一個完美數列。 輸入格式&#xff…

《STL源碼剖析常見面試問題》

1. 當vector的內存用完了,它是如何動態擴展內存的?它是怎么釋放內存的?用clear可以釋放掉內存嗎?是不是線程安全的? (1). vector內存用完了,會以當前size大小重新申請2*size的內存,然后把原來…

1034 有理數四則運算 (20 分)

本題要求編寫程序,計算 2 個有理數的和、差、積、商。 輸入格式: 輸入在一行中按照 a1/b1 a2/b2 的格式給出兩個分數形式的有理數,其中分子和分母全是整型范圍內的整數,負號只可能出現在分子前,分母不為 0。 輸出格式&…

1035 插入與歸并 (25 分)

根據維基百科的定義: 插入排序是迭代算法,逐一獲得輸入數據,逐步產生有序的輸出序列。每步迭代中,算法從輸入序列中取出一元素,將之插入有序序列中正確的位置。如此迭代直到全部元素有序。 歸并排序進行如下迭代操作&a…

迭代式失效情況

vector 向容器插入元素后: 如果容器是vector或string,且存儲空間被重新分配,則指向容器的迭代器會失效;如果存儲空間未重新分配,指向插入點位置號之前的元素的迭代器仍然有效,但是指向插入點之后的元素的迭…

1039 到底買不買 (20 分)

小紅想買些珠子做一串自己喜歡的珠串。賣珠子的攤主有很多串五顏六色的珠串,但是不肯把任何一串拆散了賣。于是小紅要你幫忙判斷一下,某串珠子里是否包含了全部自己想要的珠子?如果是,那么告訴她有多少多余的珠子;如果…

【Leetcode】111. 二叉樹的最小深度

給定一個二叉樹,找出其最小深度。 最小深度是從根節點到最近葉子節點的最短路徑上的節點數量。 說明: 葉子節點是指沒有子節點的節點。 示例: 給定二叉樹 [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回它的最小深度 2. 解題思路:…

1040 有幾個PAT (25 分

字符串 APPAPT 中包含了兩個單詞 PAT,其中第一個 PAT 是第 2 位(P),第 4 位(A),第 6 位(T);第二個 PAT 是第 3 位(P),第 4 位(A),第 6 位(T)。 現給定字符串,問一共可以形成多少個 PAT&#xff…

g

1. 何時需要成員初始化列表?過程是什么? 當初始化一個引用成員變量時;初始化一個const成員變量時;當調用一個基類的構造函數,而構造函數擁有一組參數時;當調用一個成員類的構造函數,而他擁有一組…

【Leetcode | 1】93. 復原IP地址

給定一個只包含數字的字符串&#xff0c;復原它并返回所有可能的 IP 地址格式。 示例: 輸入: "25525511135" 輸出: ["255.255.11.135", "255.255.111.35"] 方法一&#xff1a; class Solution { public:vector<string> restoreIpAddresse…

1051 復數乘法 (15 分)

復數可以寫成 ( 的常規形式&#xff0c;其中 A 是實部&#xff0c;B 是虛部&#xff0c;i 是虛數單位&#xff0c;滿足 1&#xff1b;也可以寫成極坐標下的指數形式 (&#xff0c;其中 R 是復數模&#xff0c;P 是輻角&#xff0c;i 是虛數單位&#xff0c;其等價于三角形式 (。…

【Leetcode | 13】56. 合并區間

給出一個區間的集合&#xff0c;請合并所有重疊的區間。 示例 1: 輸入: [[1,3],[2,6],[8,10],[15,18]] 輸出: [[1,6],[8,10],[15,18]] 解釋: 區間 [1,3] 和 [2,6] 重疊, 將它們合并為 [1,6]. 示例 2: 輸入: [[1,4],[4,5]] 輸出: [[1,5]] 解釋: 區間 [1,4] 和 [4,5] 可被視為重疊…

1050 螺旋矩陣 (25 分

本題要求將給定的 N 個正整數按非遞增的順序&#xff0c;填入“螺旋矩陣”。所謂“螺旋矩陣”&#xff0c;是指從左上角第 1 個格子開始&#xff0c;按順時針螺旋方向填充。要求矩陣的規模為 m 行 n 列&#xff0c;滿足條件&#xff1a;mn 等于 N&#xff1b;m≥n&#xff1b;且…

【Leetcode | 11】268. 缺失數字

給定一個包含 0, 1, 2, ..., n 中 n 個數的序列&#xff0c;找出 0 .. n 中沒有出現在序列中的那個數。 示例 1: 輸入: [3,0,1] 輸出: 2 示例 2: 輸入: [9,6,4,2,3,5,7,0,1] 輸出: 8 說明: 你的算法應具有線性時間復雜度。你能否僅使用額外常數空間來實現? class Solution { p…

1053 住房空置率 (20 分)

在不打擾居民的前提下&#xff0c;統計住房空置率的一種方法是根據每戶用電量的連續變化規律進行判斷。判斷方法如下&#xff1a; 在觀察期內&#xff0c;若存在超過一半的日子用電量低于某給定的閾值 e&#xff0c;則該住房為“可能空置”&#xff1b; 若觀察期超過某給定閾值…

1052 賣個萌 (20 分)

萌萌噠表情符號通常由“手”、“眼”、“口”三個主要部分組成。簡單起見&#xff0c;我們假設一個表情符號是按下列格式輸出的&#xff1a; [左手]([左眼][口][右眼])[右手]現給出可選用的符號集合&#xff0c;請你按用戶的要求輸出表情。 輸入格式&#xff1a; 輸入首先在前三…

1054 求平均值 (20 分)

1054 求平均值 &#xff08;20 分&#xff09;本題的基本要求非常簡單&#xff1a;給定 N 個實數&#xff0c;計算它們的平均值。但復雜的是有些輸入數據可能是非法的。一個“合法”的輸入是 [?1000,1000] 區間內的實數&#xff0c;并且最多精確到小數點后 2 位。當你計算平均…

【Leetcode | 12】342. 4的冪

給定一個整數 (32 位有符號整數)&#xff0c;請編寫一個函數來判斷它是否是 4 的冪次方。 示例 1: 輸入: 16 輸出: true 示例 2: 輸入: 5 輸出: false 方法一&#xff1a; class Solution { public:bool isPowerOfFour(int num) {// 0x55555555 二進制 1010101010101010101010…

1056 組合數的和 (15 分)

給定 N 個非 0 的個位數字&#xff0c;用其中任意 2 個數字都可以組合成 1 個 2 位的數字。要求所有可能組合出來的 2 位數字的和。例如給定 2、5、8&#xff0c;則可以組合出&#xff1a;25、28、52、58、82、85&#xff0c;它們的和為330。 輸入格式&#xff1a; 輸入在第一行…