【轉】深入理解const char*p,char const*p,char *const p,const char **p,char const**p,char *const*p,char**const p

來源:互聯網
上載者:User

標籤:

 

  

一、可能的組合:

(1)const char*p

(2)char const*p

(3)char *const p
(4)const char **p

(5)char const**p

(6)char *const *p

(7)char **const p

當然還有在(5)、(6)、(7)中再插入一個const的若干情況,不過分析了以上7中,其他的就可類推了!

 

二、理解助記法寶:

1、關鍵看const 修飾誰。

2、由於沒有 const *的運算,若出現 const * 的形式,則const實際上是修飾前面的。

比如:char const*p,由於沒有const*運算,則const實際上是修飾前面的char,因此char const*p等價於const char*p。也就是說上面7種情況中,(1)和(2)等價。 同理,(4)和(5)等價。在(6)中,由於沒有const*運算,const實際上修飾的是前面的char*,但不能在定義時轉換寫成 const(char *)*p,因為在定義是"()"是表示函數。

三、深入理解7種組合

  程式 在執行時為其開闢的空間皆在記憶體(RAM)中,而RAM裡的記憶體單元是可讀可寫 的;指標只是用來指定或定位要操作的資料的工具,只是用來讀寫RAM裡記憶體單元的工作指標 。若對指標不加任何限定,程式中一個指標可以指向RAM中的任意位置(除了系統敏感區,如作業系統核心所在地區)並對其指向的記憶體單元進行讀和寫操作(由RAM的可讀可寫屬性決定);RAM裡記憶體單元的可讀可寫屬性不會因為對工作指標的限定而變化(見下面的第4點),而所有對指標的各種const限定說白了只是對該指標 的 讀寫權限 (包括讀寫位置)進行了限定 。


(1)char *p:p是一個工作指標,可以用來對任意位置 (非系統敏感地區)進 行讀操作和寫操作 ,一次讀寫一個位元組(char佔一個位元組)。

  註: 特例: const char wang[]={"wang"}; char *p; p=wang; 是錯誤的。 所以char *p中的P不能指向常變數
(2)const char*p或者char const *p(因為沒有const*p運算,因此const修飾的還是前面的char):可以對任意位置(非系統敏感地區)進行“唯讀” 操作。(“唯讀”是相對於char *p來說所限定的內容)


(3)char *const p(const 修飾的是p):只能對“某個固定的位置” 進 行讀寫操作,並且在定義p時就必須初始化(因為在後面不能執行“p=..”的操作,因此就不能在後面初始化,因此只能在定義時初始化)。(“某個固定的位 置”是相對於char *p來說所限定的內容)


可以總結以上3點為:char *p中的指標p通常是”萬能”的工作指標 ,而(2)和(3)只是在(1)的基礎上加了些特定的限制 ,這些限制在程式中並不是必須的,只是為了防止程式員的粗心大意而產生事與願違的錯 誤。
另外,要明白“每塊記憶體空間都可有名字;每塊記憶體空間內容皆可變(除非有所限) ” 。比如函數裡定義的char s[]="hello";事實上在進程的棧記憶體裡開闢了6個變數共6個位元組的空間,其中6個字元變數的名字分別為:s1[0]、s1[1]、 s1[2]、s1[3]、s1[4]、s1[5](內容是‘\0‘)

{

待驗證 : 還有一個4位元組的指標變數s 。不過s是“有所限制”的,屬於char *const類型,也就是前面說的 (3)這種情況,s一直指向s[0], 即(*s==s[0]==‘h‘),可以通過*s=‘k‘來改變s所指向的 s[0]的值,但不能執行(char *h=“aaa”;s=h;)來對s另外賦值。

}

(4)上面的(2)和(3)只是對p進行限定,沒有也不能對p所指向的空間進行限定,對於"char s[]="hello";const char*p=s;" 雖然不能通過*(p+i)=‘x‘或者p[i]=‘x‘來修改數組元素s[0]~s[4]的值,但可以通過*(s+i)=‘x‘或者s[i]=‘x‘來修改原數組元素的值--RAM裡記憶體單元的可讀可寫屬性不因對工作指標的限定而改變,而只會因對其本身的限定而改變。如const char c=‘A’,c是RAM裡一個記憶體單元(8位元組)的名字,該記憶體單元的內容只可讀,不可寫。

 

(5)const char **p或者char const**p :涉及兩個指標p和 *p。由於const修飾char ,對指標p沒有任何限定,對指標*p進行了上面情況(2)的限定。

 

(6)char *const *p:涉及兩個指標p和 *p。由於const修飾前面的char*,也就是對p所指向的內容*p進行了限定(也屬於前面的情況(2))。而對*p來說,由於不能通過"*p=..."來進行另外賦值,因此屬於前面的情況(3)的限定。

 

(7)char **const p : 涉及兩個指標p和 *p,const修飾p,對p進行上面情況(3)的限定,而對*p,沒有任何限定。

 

四、關於char **p 、const char **p的類型相容性問題

1、問題

char *p1;const *p2=p1;//合法

char **p1;const char**p2=p1;//不合法,會有警告warning: initialization from incompatible pointer type

char **p1;char const**p2=p1;//不合法,會有警告warning: initialization from incompatible pointer type

char**p1;char*const*p2=p1;//合法

2、判斷規則

明確const修飾的對象!對於指標p1,和p2,若要使得p2=p1成立,則可讀做 :

“p1是指向X類型的指標,p2是指向“帶有const限定”的X類型的指標 “。只要二者的X類型一樣,就是合法的。

char *p1;const *p2=p1;//合法:p1是指向(char)類型的指標,p2是指向“帶有const限定"的(char)類型的指標。

char **p1;const char**p2=p1;//不合法:p1是指向(char*)類型的指標,p2是指向 ((const char)*)類型的指標。

char **p1;char const**p2=p1;//不合法;與上等價。

char**p1;char*const*p2=p1;//合法: p1是指向(char *)類型的指標,p2是指向“帶有const限定"的(char*)類型的指標。

五、其他

1、含有const的單層或雙層指標的統一讀法:

“p是一個指標,是一個[“帶有const限定”的]指向[”帶有const限定”的]X類型的指標”。

l例如:const char* const *p就是說:p是一個帶有const限定的指向帶有const限定的(char*)類型的指標。

2、定義時const修飾的對象是確定的,但不能在定義時加括弧,不然就和定義時用“()”表示的函數類型相混淆了!因此定義時不能寫(char *)const *p或者(const char) **p。

【轉】深入理解const char*p,char const*p,char *const p,const char **p,char const**p,char *const*p,char**const p

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.