常量指針是指向常量的指針,指針指向的記憶體位址的内容是不可修改的。
即指針指向了一個常量,但是指針本身是一個變量
定義<code>const int *p=&a;</code>
這條語句告訴編譯器,*p是常量,不能将*p作為左值進行操作。但這裡的指針p還是一個變量,它的内容存放常量的位址,是以先聲明常量指針再初始化是允許的,指針也是允許修改的
示例
1
2
3
4
5
指針常量是指針的常量,它是不可改變位址的指針,但可以對它所指向的内容進行修改。
即指針本身是一個常量,但是指着指向一個變量
指針常量定義<code>int * const p=&a;</code>
告訴編譯器,p是常量,不能作為左值進行操作,但允許修改其指向的内容,即*p是可修改的。指針常量必須在聲明的同時對其初始化,不允許先聲明一個指針常量随後再對其指派,這和聲明一般的常量是一樣的
如其名,不僅僅指針本身是一個常量(不可以修改其指向,指針指向的也是一個常量)
定義為<code>const int * const p = &ca;</code>
依據右左法則右左法則:首先從最裡面未定義的辨別符看起,然後先往右看,再往左看。每當遇到圓括号時,就應該掉轉閱讀方向。一旦解析完圓括号裡面所有的東西,就跳出圓括号。重複這個過程直到整個聲明解析完畢。(右左法則不是c标準裡面的内容,它是從c标準的聲明規定中歸納出來的方法。c标準的聲明規則,是用來解決如何建立聲明的,而右左法則是用來解決如何辯識一個聲明的)
當然我們也可以依據編譯原理的思想,來分析const修飾的語義
指針常量
定義
分析
char * const cp
右左法則
cp is a const pointer to character
語義
are neat
常量指針
const char * p;
char const * p
c++标準規定,const關鍵字放在類型或變量名之前等價的,c++裡面沒有const*的運算符
p is a pointer to const character;
const修飾的char *, 說明該指針指向的變量是一個常量
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
tcc的運作結果

gcc的運作結果
clang的運作結果
我們拿了大神法布裡斯·貝拉(fabricebellard)的tcc與現代優化技術下的編譯器的編譯結果進行對比,我們可以很明顯的發現。
我們所關注的是,一個不同支之處在于在現代優化技術下的編譯器,相同的字元串變量在記憶體中隻存儲了一份, 字元數組除外,因為字元數組本身是一段連續存儲的字元變量。
但是我之前上面的代碼其實有點疑問,那就是<code>char * const pstr = "abcd"</code> 時候,我們的常理會認為pstr是一個指針常量,那麼我麼就應該不能修改其指向,但是可以修改其指向的字元串的值,但是結果真的如此麼
我們從上面一個示例程式可以很明顯的發現,pstr3和pstr4作為指針常量,指針本身的讀寫(主要是寫)限制,是由編譯器處理的,是以存在了棧區,但是字元串本身”abcd”卻放在了代碼段(或者說常量區)。那麼我們可以大膽假設
1 指針常量本身的指向無法修改,這個由編譯器在編譯階段進行檢查
2 指針所指向的字元串也是無法修改的,因為字元串常量存儲在代碼段(或者常量區,因為有些分類中是不存在常量區的,常量區與代碼段共同組成代碼區)中,這段區域是由作業系統管理的隻讀段
回答的大神們都很好的回答了這個問題,把大家的答案總計一下大緻說了這樣一個意思
<code>char * const pstr = “abcd”</code> 這條語句是在定義常量時同時進行了初始化,那麼初始化的變量就作為一個文本常量存儲在了常量區。
我們來類比如下一條語句<code>const int a = 10;</code> 我們難道能夠繞過a來修改變量本身的值10麼,顯然答案是否定的,當然和這條語句對比并不是很貼切,那麼我們來看下面一條
是以請看下面代碼
是以下面的代碼無論const存在與否,都是在修改常量區的代碼
必然導緻訪存錯誤,引起segmentfault
如果你非要這樣做的話請使用
或者更複雜點
轉載:http://blog.csdn.net/gatieme/article/details/48896847