前言:很多人都把const int * 、int * const、int const* 的區別和聯繫搞混,我自己在學習C++的過程中,也經常性 弄不 清楚,今天特意總結一下,作爲學習筆記記錄下來。
一,const修飾符用於指針
將const用於指針有些很微妙的地方,有兩種不同的方式將const關鍵字用於指針。第一種方法是讓指針指向一個常量對象,這樣可以防止使用該指針來修改所指向的值,第二種方法是將指針本身聲明爲常量,這樣可以防止改變指針的位置。
聲明一個指向常量的指針a:
int y = 1;
const int * a = &y;
該聲明指出,a指向一個const int,這裏爲1,因此不能使用a來修改這個值。換句話說,*a的值爲const,不能被修改,但是a的聲明並不意味着它指向的值實際上就是一個常量,而只是意味着對a而言,這個值是常量。a指向y,而y不是const,可以通過y變量來修改y的值,但不能使用a指針來修改。
const int m = 9;
const int * n = &m; // (1)
int * t = &m; //(2)
上面的(1)和(2)中看到了什麼,(2)將const的地址賦給了常規指針,(1)將const地址賦給了const指針,這兩張是否正確呢,答案顯然(2)不對,因爲C++禁止將const的地址賦給非const指針,如果非要這樣做,只能使用強制類型轉換來突破這種限制。
int m = 1;
const int * n = &m; //(3)
int * const h = &m; //(4)
(3)中聲明的const只能防止修改n指向的值,而不能防止修改n的值,也就是說可以將一個新地址賦給n;但仍然不能使用n來修改它指向的值,不允許使用n來修改m的值,但允許將n指向另一個位置。(4)中關鍵字const的位置與之前的不同,這種聲明格式使得h只能指向m,但允許使用h來修改m的值。
二,int const * 與const int *
int const * a 與const int * a是沒有任何區別的,它們的效果是一樣的,都表示a指向一個const int,它總是把它指向的目標當做一個int常量。不能使用a來修改這個指向的地址的值,但是可以重新指向其他地址。即*a的值是const,不能被修改。
三,const int * const 與 const int const *
int trouble = 2;
const int * const flag1 = &trouble; //(5)
const int const * flag2 = &trouble; //(6)
其中(5)flag1只能指向trouble,而flag1不能用來修改trouble的值,即flag1和*flag1都是const。指向的地址和指向的地址的值都不能改變。
其中(6)同(5)的用法類似,也是指針指向的內存地址不可變,並且指針指向的內存地址的值也不能被修改。
四,牛客網例題分析
請聲明一個指針,其所指向的內存地址不能改變,但內存中的值可以被改變。
正確答案: B 你的答案: C (錯誤)
const int const *x = &y;
int * const x = &y;
const int *x = &y;
int const *x = &y;
const int * const x = &y;
我們始終記住若const限定符在*之前,則const限定的是*ptr而不限定ptr。也就是說,ptr可以改變其所指向的對象,但不能通過該指針修改其所指向對象的值。 若const限定符在*之後,則const限定的是ptr而不限定*ptr。也就是說,ptr不可以改變其所指向的對象,但能通過該指針修改其所指向對象的值。 若在*之前有const限定符且在*之後也有const限定符,則ptr與*ptr都被限定。也就是說,ptr既不可以改變其所指向的對象,也不能通過該指針修改其所指向對象的值。 只要在*之後有const 限定符,則該指針在聲明時必須初始化。
A中指向的內存地址不可變,指向的內存地址的值也不可變
B中指向的內存地址不可變,但是指向的內存的地址的值可以改變。
C中指向的內存地址可以改變,但是指向的內存的地址的值不能改變。
D中指向的內存地址可以改變,但是指向的內存的地址的值不能改變。
E中指向的內存地址不可變,指向的內存地址的值也不能改變。
如有錯誤歡迎指正,謝謝各位看官!