指標和const的2, 3事

2021-07-10 14:38:03 字數 2948 閱讀 8109

const

char *a; // *a是const, a可變

char

const *a; // *a是const, a可變

//用上述方式來遍歷乙個一維陣列,又不更改其內的資料

int foo(const

char *a);

//注意:const (char *) p;和(char *) const p;這是錯誤的,括號會被當成強制型別轉換。

//類似陣列名,指向的位置是不變的,但是可以修改陣列內的資料

const* char a; //error,無法編譯

char* const a; // a是const,*a可變

char

const* const a; //a和*a都是const

const

char* const a; //a和*a都是const

//對於1級指標,有乙個簡便的區分方法:沿著*號劃一條線,

//如果const位於*的左側,則const就是用來修飾指標所指向的變數,

//即指標指向為常量;如果const位於*的右側,const就是修飾指標本身,

//即指標本身是常量。

//通用的方法是,const修飾的是其後面出現的*,不修飾它前面的

#include 

#include

void testfirstpointer1(const

char* p)

void testfirstpointer2(char* const p)

void testfirstpointer3(const

char* const p)

void testsecondpointer1(const

char** p)

void testsecondpointer2(char* const* p)

void testsecondpointer3(char** const p)

//使用gcc version 5.2.1 20151010

//下述測試,標註wrong是的編譯器編譯的時候會出warning

//沒有標註的編譯器未給出任何資訊,編譯器認為是正確的使用

//標註right?後面給予解釋

int main()

//在任何情況下,都可以向const t型別的指標傳入t型的指標

//(t表示任意資料型別),但反過來卻不行。

//因很簡單,如果反來過可行,我們就可以借助普通指標來修改const型

//指標指向的內容,這恐怕不是我們想要的結果。

//但是這條規則是否適用於const修飾的二級指標呢?

//比如給const char **的指標傳入乙個char **的值,會不會保證萬無一失呢?

//這種情況下編譯器一般會給出乙個warning,曾以為這個warning是無關緊要

//的,只是編譯器太敏感了,只到後來 看來這個例子,我才彷彿明白了什麼:

const

char c = 'x';

char *p1;

const

char **p2 = &p1;//用char **的值賦給const char **, warning: 不匹配

*p2 = &c;//用const char * 給const char *賦值,完全沒問題

//**p2 = 'y'; error,不能修改const

*p1 = 'y';//給char *指向的內容賦值,沒問題!但這兒會發生什麼事情

printf("%c \n", c); //c值成為y

//除了第3行出有乙個warning外,其餘的都沒任何問題,

//但是經過第4步的操作,p1已經指向的c,這是乙個不可修改的變數,

//第5步,修改了乙個const char,嗚呼哀哉!

//所以正確的是:

const

char c = 'x';

const

char *p1;

const

char **p2 = &p1;//用char **的值賦給const char **,匹配

//char **const p2 = &p1; 這樣宣告,下面語句出warning

//char *const *p2 = &p1; 這樣宣告,下面語句編譯不過

*p2 = &c;//用const char * 給const char *賦值,完全沒問題

*p1 = 'y';//有問題,不能給const char* 賦值,error,編譯不通過

//簡單來說,兩個問題如下表達:

const

char* 和 char* const不匹配

char* const 和 const

char*確是匹配的!

char* const*和char** const不匹配

char** const和char* const*確是匹配的!

# include

# include

void testlevel1_1(char* const p)

void testlevel1_2(const

char *p)

void testlevel2_1(char** const p)

void testlevel2_2(char* const* p)

int main(int argc, char **argv)

//我們好像明白了,為什麼這兩個例子是特殊的,因為所有的函式都是值傳遞,

//無論是指標還是非指標,指標傳遞是一種特殊的值傳遞,也就是傳遞位址,

//所有函式內部對於形參位址的修改,不會影響到外邊傳進來的指標的位址,

//所以char* const可以放心的傳入const char *,因為本質上函式內部根本無法修改位址的值

c專家程式設計

指向const的指標和const指標

指向const的指標 int gorp 16 int chips 12 const int p snack gorp 其中p snack指向乙個const int。p snack 20 不被允許,p snack的值為const,禁止修改p snack指向的值,p snack chips 可以執行,p...

const指標和指向const物件的指標

1.有關const指標和指向const物件指標的一道題 首先要說明的是怎麼來判斷const指標還是指向const的指標 如果const後面跟的是型別,那麼const是用來修飾物件的,所以它是指向const物件的指標 但是如果const後面跟的是指標本身,那麼const是用來修飾指標的,所以它是con...

const指標和指向const物件的指標

在c 中,帶const修飾符的指標很容易混淆,做個總結 由於const物件的值不可以修改,所以不允許通過指標來改變其指向的const值,例如如下定義 const double cptr 這裡cptr是乙個指向double型別const物件的指標,const限定了cptr指標所指向的物件型別,而非cp...