天天看點

2021.2.1學習日志2.4 const限定符

指向指針的引用

​ 引用本身不是一個對象,是以不能定義指向引用的指針。但指針是對象,是以存在對指針的引用:

int i=42;int *P;

// p是一個int型指針

int *&r = P;

// r是一個對指針p的引用

r=&i;

//r引用了一個指針,是以給r指派&i就是令p指向i

*r= 0;

//解引用r得到i,也就是p指向的對象,将i的值改為0


           

​ 要了解r的類型到底是什麼,最簡單的辦法是從右向左閱讀r的定義。離變量名最近的符号(此例中是&r的符号&)對變量的類型有最直接的影響,是以r是一個引用。聲明符的其餘部分用以确定r引用的類型是什麼,此例中的符号*說明r引用的是一個指針。最後,聲明的基本資料類型部分指出r引用的是一個int指針

​ 面對一條比較複雜的指針或引用的聲明語句時,從右向左閱讀有助于弄清楚它的真實含義

2.4 const限定符

c 語言部分的稱述

​ 通過采用指針或數組作函數參數,可使調用者獲得修改後的資料,但有時我們隻希望将資料傳到被調函數内部,而并不希望它們在麗數内被修改,此時,為防止資料被意外修改,也為了讓函數的功能更明确(明确表示程式員的意圖,不希望它們被修改),可使用const對參數進行限定。如例10.6所示,可将MyStrlen()聲明為:

​ 或者

​ 事實上,當聲明一個指針變量時,這個指針變量本身的值以及它所指向的資料都可被聲明為const。 const位于聲明語句中的不同位置,将表示不同的含義。

​ (1) const放在類型關鍵字的前面。

​ 假設有如下變量聲明語句:

int a, b;

​	const int *p = &a;
           

​ 按照從右到左的順序,可将這條變量聲明語句讀作:“p是一個指針變量,可指向一個整型常量( Integer Constant)”。它表明p是一個常量,而p不是。由于p是隻讀的,是不可以在程式中被改的,是以一且将 °p作為左值在程式中對其進行财值,将被視為非法操作。注意:雖然這裡印的值是不可修改的,但p指向的變量a的值仍然是可以修改的,即對a執行指派操作是合法的。因指針變量p的值是可以修改的,是以這裡如果執行指派操作p=&b也是合法的.經過這個指派之後,指針變量P就不再指向變量a而指向變量b了。

​ (2) const 放在類型關鍵字的後面和*變量名的前面。

​ 按照從右到左的順序,可将這條變量聲明語句讀作:“p是一個指針變量,可指向一個常量整數( Constant Integer)”。它表明p是一一個常量,而p不是。由于p是隻讀的,是以不能使用指針變量p修改這個“為常量的整型數" ,它和第一種情況是等價的。

​ (3) const放在類型關鍵字*的後面,變量名的前面。

​ 按照從右到左的順序,可将這條變量聲明語句讀作:“p是一個指針常量,可指向一個整型(Integer)資料”。它表明p是一個常量,而卻不是。由于p是一個常量指針,是隻讀的,其值是不可以被修改的,是以在程式中不能修改指針p.讓它指向其他變量,但是它所指向的變量的值是可以修改的。例如,此時執行*p=20這樣的指派操作是合法的,而執行p=&b這樣的指派操作就是非法的。

​ (4)一個const放在類型關鍵字之前,另一個const放在類型關鍵字之後和變量名之前。

​ 按照從右到左的順序,可将這條變量聲明語句讀作:“”P是一個指針常量,可指向一個整型常量(neger Costn)"。它表明p和。p都是個常量,都是隻讀的。這時,無論執行.p=20還是執行p=&b這樣的指派操作,都将被視為非法操作。

​ 在以上四種用法中,第一種用法較為常用.C語言的許多标準庫函數都在函數的某些指針參數的類型前加上了co限定符,目的就是隻允許函數通路該指針參數指向的位址單元中的内容,不允許修改其内容,進而對參數起到一定的保護作用,減少程式出錯的機會。

c++部分

​ 和c一樣,const限定符是用來定義一種變量,它的值不能被随意修改。

​ 像是用來表示緩沖區的大小,一來容易程式員的修改,二來可以避免程式修改了此值。

​ 因為const的對象一旦建立後其值就不能再次進行修改,是以const對象必須進行初始化。

初始化和const

​ 正如之前反複提到的,對象的類型決定了其上的操作。與非const類型所能參與的操作相比,const類型的對象能完成其中大部分,但也不是所有的操作都适合。主要的限制就是隻能在const類型的對象上執行不改變其内容的操作。例如,const int和普通的int一樣都能參與算術運算,也都能轉換成一一個布爾值,等等。

預設狀态下,const對象僅在檔案内有效

​ 當以編譯時初始化的方式定義一個const對象時,就如對bufSize的定義一樣:

const int bufSize = 512; //輸入緩沖區大小
           

​ 編譯器将在編譯過程中把用到該變量的地方都替換成對應的值。也就是說,編譯器會找到代碼中所有用到bufSize的地方,然後用512替換。

​ 為了執行上述替換,編譯器必須知道變量的初始值。如果程式包含多個檔案,則每個用了const對象的檔案都必須得能通路到它的初始值才行。要做到這一點, 就必須在每一個用到變量的檔案中都有對它的定義(參見22.2節,第41頁)。為了支援這一用法,同時避免對同一變量的重複定義,預設情況下,const對象被設定為僅在檔案内有效。當多個檔案中出現了同名的const變量時,其實等同于在不同檔案中分别定義了獨立的變量。

​ 某些時候有這樣種const 變量,它的初始值不是一 個常量表達式,但又确實有必要在檔案間共享。這種情況下,我們不希望編譯器為每個檔案分别生成獨立的變量。相反,我們想讓這類const對象像其他(非常量)對象樣工作, 也就是說, 隻在一個檔案中定義const,而在其他多個檔案中聲明并使用它。

​ 解決的辦法是,對于const變量不管是聲明還是定義都添加extern關鍵字,這樣隻需定義一次就可以了:

/ file_ 1.cc定義并初始化了一個常量,該常量能被其他檔案通路

​	extern const int bufsize = fcn();

​	/ file_ 1.h頭檔案

​	extern const int bufSize; //與file 1.cc中定義的bufSize是同一個
           

​ 如上述程式所示,file_ 1.cc 定義并初始化了bufSize.因為這條語句包含了初始值是以它(顯然)是一次定義。然而,因為bufSize是一個常量,必須用extern加以廈定使其被其他檔案使用。

​ file_ 1.h頭檔案中的聲明也由extern做了限定,其作用是指明bufSize并非本檔案所獨有,它的定義将在别處出現。

​ 如果想在多個檔案之間共享const對象,必須在變量的定叉之前添加extern關鍵字。

2.4.1 const常量的引用

​ 可以把引用綁定到const對象上,就像綁定到其他對象上一樣,我們稱之為對常量的引用。與普通的引用不同的是,對常量的引用不能被修改。

繼續閱讀