const常用來修飾普通變數,指標變數,甚至是函式的返回值,可以提高程式的健壯性,其用的最多之處是用來修飾函式的形參,防止修改了呼叫函式中實參指向位址中的資料及在被調函式執行中修改了形參值。
本文主要討論c語言中const的使用規則及其含義,下文由淺入深展開討論。
基本規則:
規則1、const修飾後的變數,變成唯讀(read-only),稱唯讀(read-only)變數或const變數;
規則2、唯讀變數在宣告時必須同時初始化,之後變成唯讀,不可再修改;
規則3、const放在型別前與型別後效果是等價的;
規則4、const變數初始化時,可以將同型別普通變數賦給它;
規則5、普通非指標變數,可以將同型別const變數賦給它;
規則6、指向普通型別的指標,是不可以將指向const修飾型別的指標賦給它。
總的原則:
不要嘗試去改變const修飾的量的值
(編譯報錯還好,萬一不報錯,如通過取const變數位址後修改或者是強制型別轉換後修改,程式的執行可能會出現難以想象的錯誤)。
int b = 100;
int const a = 100;
等價於const int a = 100;
說明:a是乙個整型變數,被const修飾,宣告時必須同時初始化,之後不要嘗試修改a的值,尤其是通過指標。
初始化的值可以是普通常量,也可以是普通變數,當然同型別的const變數更是可以的。
const int c = ;
說明:陣列的元素型別是const int,即c[0] c[1] c[2]均被const修飾,不要嘗試修改。
形式1:
int* const p = &b;
說明: p是乙個指向int型的指標,被const修飾,宣告時必須同時初始化, 之後不要嘗試修改p的值。
形式2:
const int* p;
p = &a;
等價於int const* p;
p = &a;
說明:其實這裡p就是乙個普通指標,並沒有被const修飾,即可以修改p的值。但p指向的是const int*,即指向的是乙個被const修飾的int,
也就是*p是被const修飾,不要嘗試修改*p的值;
p+i與p是同型別(i在這裡是個整數),顯然*(p+i)指向的也是const int變數,也是不能修改它的值。
形式3:
const int* const p = &a;
說明:形式3就是形式1與形式2的合併,p及*p均被const修飾;宣告時必須同時初始化。
之後不要嘗試修改p與*p;
規則4、5、6主要是涉及到乙個型別的轉換。
int a;
const int ca = a; //規則4 const變數初始化時,可以將同型別普通變數賦給它;
int* pa;
int* const pca = pa; //pca是const變數,指向的是int*,符合規則4
a = ca; //規則5 普通非指標變數,可以將同型別const變數賦給它
const int* cpa; //cpa不是const變數,是乙個普通指標變數,只是它指向的是乙個const型
pa = cpa; /* 編譯報錯,根據規則6、指向普通型別的指標,是不可以將 指向const修飾型別的指標賦給它。原因很簡單,這樣賦值成功的話,
*pa將會改變*cpa的值,而*cpa是指向const int,唯讀的 */
cpa = pa;//編譯通過,即int*是可以轉換為const int*的。
char *p = "abc"; //大多數編譯器會產生告警或報錯,普通指標指向了不可改的常量區;
const char *p = "abc";//編譯通過
char arr = "abc";//編譯通過,會給陣列arr分配4個位元組,存放'a''b''c''\0',
通過以上的分析:
const修飾普通變數:const int <=> int const,其實也就是一種。
const修飾指標變數:
const int * <=> int const*
int* const
const int* const <=> int const* const
其實就三種。
形式const
可賦值給
不可賦值給
int a
無const int
const int a
修飾a,a是唯讀的
intint* pa
無int* const
const int*
const int* const
int* const pca
修飾指標本身pca,pca唯讀
int*
const int*
const int* const
const int* cpa
修飾指標指向值*cpa,*cpa唯讀
const int* const
int*
int* const
const int* const cpca
修飾cpca
修飾*cpca
二者都是唯讀
const int*
int*
int* const
c語言知識點:c語言中函式的形參是實參的乙份拷貝。
形式1:
int func(const int a);
說明:形參:a被const修飾,在func內部,不能修改a的值。
實參:int型,有無const修飾均可。
形式2:
int func(const int *p);
說明:形參:是指標p, 其指向的是const int型,即指向被const修飾的int型變數。func內部不能修改*p和*(p+i)的值,可以修改p的值。
實參:形參是指標,實參也要是指標,且其指向及本身有無const修飾均可。
形式3:
int func(int* const p);
說明:形參:是指標p,被const修飾,其指向的是int型。func內部不能修改p的值,但可以修改*p和*(p+i)的值。
實參:形參是指標,實參也要是指標,且其指向及本身有無const修飾均可。
形式4:
int func(const int* const p);
說明:形參:是指標p,被const修飾,同時*p也被const修飾。func內部不能修改p的值,也可以修改*p和*(p+i)的值。
實參:形參是指標,實參也要是指標,且其指向及本身有無const修飾均可。
形式5:
int func(const int arr);
等價於形式2
int func(const int *p);
說明:c語言的知識點,一維陣列作形參,其實就是相當於乙個指向元素型別的指標。
const int** pp; <=> int const** pp; //規則3
說明: const 是用於修飾**pp, 即**pp不可修改
int*const* pp
說明:const是用於修飾*pp, 即*pp不可修改
int ** const pp
說明: const用於修飾pp, 即pp不可修改,是個const變數,宣告時必須初始化
來個終極大魔王:
const int*const* const pp
說明:pp *pp **pp 均被const修飾,pp是個const變數,宣告時必須同時初始化。
關於char**不能賦值給const char**卻可賦值const char *const*的問題**:
假如通過強制型別轉換char**pp0賦給了const char **pp1, *pp1也等於*pp0,同時由於*pp1未被const修飾,可以重新賦值,可以賦const char*,賦值的同時相當於也賦給了*pp0這個,此時雖然**pp1是唯讀不能修改,但是**pp0卻能修改,能通過**pp0將const char給改了,顯然不行的。倘若*pp1也被const修飾(const char *const*),那麼,*pp1不可以重新賦值,那麼自然也不出會修改const char。
int main()
如果pp1的型別是const char *const* pp1; 那麼*pp1 = s;這條語句就不通,即不能給常量重新賦值。
const 修飾變數或者指標
最近看effective c 這本書,發現之前寫的 有很多不好的習慣,之前看過這本書,但是總是對裡面的提的建議忘記,所以記下來加以理解會為未來寫 具有更好的習慣。特別是const修飾變數,指標等等。之前總是覺得它好麻煩,約束太強了 缺乏對const的理解 後面發現自己寫的 越多,發現越是難以控制大量...
const修飾指標
1.指向const資料的非const指標 const int countptr 這個宣告從左到右讀,countptr 是乙個指向整數常量的指標 2.指向非const資料的const指標 int const ptr x 這個ptr指標就是const指標,宣告為const的指標必須在宣告時進行初始化。指...
const修飾指標
書寫形式為 int countptr 特點 指標的指向可以被修改,指向的資料可以被修改 includeint main 書寫形式為 const int countptr 特點 指標的指向可以被修改,指向的資料不能被修改 includevoid func const int int main void...