常量指針與指針常量

常量指針和指針常量是兩個常常出現的概念,今天作個小小總結。c++

文章各部分的內容都是很容易理解的,而且附加代碼說明,一切的前提是理解文章2.1和2.2部分,因此搞好基礎再日後看吶。乾貨在嫌長的直接跳到結論去。git

廢話

最近在看VC++,看到書裏有提這兩個概念,學C的時候也有這兩個概念,學C++的時候也有頂層const和底層const(這個我懂是懂,但從理解層次上不是那麼懂爲何叫作頂層和底層)。因此就是這個知識點很常見啦,但彷佛不少人很迷惑,或者說理解着不舒服。因而個人「神邏輯」就來了。github

我對它們的理解

主要是翻譯問題

常量指針、指針常量這種名詞是英文翻譯過來的,因此中文會有點拗口。常量的、指針的,咱們生活中是沒有這樣的詞的。函數

英文裏是這樣的兩個東西:pointer to const, const pointer。翻譯

pointer是指針的意思;const是constant的縮寫,做名詞是常量的意思,做形容詞是不變的的意思。指針

這兩個詞:pointer to const, const pointer。中文有兩種翻譯方法:code

翻譯方法 pointer to const const pointer
第一種 指向常量的指針(常量指針) 不變的指針(指針常量)
第二種 指向常量的指針(指針常量) 不變的指針(常量指針)

說來講去都是翻譯的問題。英文裏很容易能看懂的意思,換成中文就有兩種換法。遊戲

我同意第一種翻譯方法,由於它更符合中文習慣。內存

第二種方法確實不應有指針常量這個說法,太不合中文習慣。get

因此要討論中文版的話,若是出現指針常量,也應該是第一種方法。

下面是一篇講常量指針和指針常量的文章:

https://www.thegeekstuff.com/2012/06/c-constant-pointers換成英文就不用玩文字遊戲了

因此呢,本質上應該用英語去講。但本篇是講中文版的一種方法。(去百度也會發現有兩種說法,緣由是翻譯不一樣)。

基礎

本文用第一種說法,常指是pointer to const,指常是 const pointer。

常指、指常就是兩個詞而已,都是四個字。把前邊的兩個字當作形容詞(是用來修飾後邊的名詞的),後邊的名詞纔是重點。

指針就是地址嘛,常量就是不能夠修改的量(初始化不算作賦值,不算作修改)。

注意區分指針自己(的內容)和指向的內存的內容。

修改指針即改變指針自己的內容,修改內存或者說修改內存內容就是修改指針指向的內存中的內容。這樣講的很清楚了吧.....…..

常量指針

常量指針中的常量呢,指的是這個指針的做用是常量性的、無權修改的,即不能夠經過該指針修改內存中的內容,並不表明指向的內存不修改,注意前邊有經過二字。

這個詞也有指向常量的指針的叫法,我認爲這個中文叫法是不許確的甚至是錯誤的。若是說常量指針是指向常量的指針,我認爲這句話最直接的意思是說指針指向的內存是常量,這個意思是錯誤的,會誤導他人,因此我不提倡這樣叫它。證實參見文章3.3部分

在討論問題的時候,互相知道對方說的是什麼東西很是重要~,好比c++裏的默認構造,沒有構造函數這樣的句子,不一樣人的理解方式不一樣,這些概念理解也是討論進行的一個前提。

指針常量

這裏的指針呢,指的是這個常量是一個地址

如何根據定義判斷類型

//代碼1
const char * p; //常量指針
char const * p; //常量指針 跟上一句等效
char * const p; //指針常量

根據const和*的相對位置

const 在*左邊=》常量指針;反之,指針常量。

根據誰離變量名近

const近=》指針常量;反之,常量指針。(const就是不變嘛,*就是指針,因此理解是很重要的,也就是2.1

代碼驗證

常量指針

//代碼2
//char ch[] = "HelloWorld!";
const char* pStr1=ch;   //定義常量指針
//1.常量指針自己的值能夠修改
pStr1 = nullptr;    //correct
//2.不能經過常量指針修改它所指向的內存中的內容(注意經過二字,不要誤會常量指針)
*pStr1 = 'h';       //error
*(pStr1 + 1) = 'E'; //error
pStr1[2] = 'L';     //error

指針常量

//代碼3
//char ch[] = "HelloWorld!";
//指針常量(頂層const)
char * const pStr2 = ch;    //定義並初始化
//1.是常量,不能夠被賦值(不把初始化叫作賦值)
pStr2 = nullptr;        //error

常量指針容易被誤解的地方

//代碼4
int n = 0;  //定義變量n
const int * p1 = &n;    //常量指針p1
int * const p2 = &n;    //指針常量p2
*p1 = 3;    //error 由於不能經過常量指針修改內存中的內容,劃重點!:但這不是說指向內存中的內容不可修改
n = 3;      //correct   這是對的,由於n是變量啊
*p2 = 3;    //correct 指針常量部分的代碼就有體現,很少說
//代碼5
const int n = 0;    //定義變量n
const int * p1 = &n;    //常量指針p1
int * const p2 = &n;    //error 錯誤的 緣由見下-指針間的賦值
*p1 = 3;        //error 緣由是常指不可修改內存
n = 3;          //error 緣由是n是變量

代碼4和代碼5中的常量指針p1都不能改變內存中內容,但內存中內容是否可修改是不必定的。(代碼4的第5第6行要好好看)

緣由是:常量指針不能夠修改內存是由於不能夠經過常量指針修改內存所致(你不經過常量指針的話,變量是否能夠修改就不必定了)

結論

常量指針

在這裏指pointer to const。指針做用是常量性的,不能夠經過它修改指向內存(容易被誤會成內存必定不可修改)。

指針常量

英文裏指const pointer。指針是一個常量,指針自己不能夠被修改。

做者:@臭鹹魚

本文爲做者原創,轉載請註明出處:https://chouxianyu.github.io/2018/08/26/常量指針與指針常量/#more

歡迎轉發和評論

相關文章
相關標籤/搜索