天天看點

C/C++中的const--常量指針與指針常量 問題解析 const進階 疑問

常量指針是指向常量的指針,指針指向的記憶體位址的内容是不可修改的。

即指針指向了一個常量,但是指針本身是一個變量

定義<code>const int *p=&amp;a;</code>

這條語句告訴編譯器,*p是常量,不能将*p作為左值進行操作。但這裡的指針p還是一個變量,它的内容存放常量的位址,是以先聲明常量指針再初始化是允許的,指針也是允許修改的

示例

1

2

3

4

5

指針常量是指針的常量,它是不可改變位址的指針,但可以對它所指向的内容進行修改。

即指針本身是一個常量,但是指着指向一個變量

指針常量定義<code>int * const p=&amp;a;</code>

告訴編譯器,p是常量,不能作為左值進行操作,但允許修改其指向的内容,即*p是可修改的。指針常量必須在聲明的同時對其初始化,不允許先聲明一個指針常量随後再對其指派,這和聲明一般的常量是一樣的

如其名,不僅僅指針本身是一個常量(不可以修改其指向,指針指向的也是一個常量)

定義為<code>const int * const p = &amp;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的運作結果

C/C++中的const--常量指針與指針常量 問題解析 const進階 疑問

gcc的運作結果

C/C++中的const--常量指針與指針常量 問題解析 const進階 疑問

clang的運作結果

C/C++中的const--常量指針與指針常量 問題解析 const進階 疑問

我們拿了大神法布裡斯·貝拉(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

繼續閱讀