【尊重】
一、const的作用 :
const是c語言的一種關鍵字,它所限定的變數是不允許被改變的,從而起到保護的作用!const關鍵字可以用於修飾變數,引數,返回值,甚至函式體。const可以提高程式的健壯性,減少程式出錯。
(一)const用於定義常量和修飾變數
當定義某個變數時,用const修飾,則該變數就變為常量,其值定義後就不能再改變了,如:const int x=1;常量x的值不能再改變了。
type const valuename = value; //type表示資料型別int、long、float等
const type valuename = value; //type表示資料型別int、long、float等
(1)const 修飾變數,表示該變數不能被修改。
1、const char *p 表示指標p指向的內容不能改變
2、char * const p,就是將p宣告為常指標,它的位址不能改變。
3、這種const指標是前兩種的結合,使得指向的內容和位址都不能發生變化.
const double pi = 3.14159;//pi是常數
const double *const pi_ptr = π
(二)const修飾函式形式引數
(1)傳遞過來的引數在函式內不可以改變(無意義,因為var本身就是形參)
void function(const int var);
(2)引數指標所指的內容為常量不可變
void function(const char* var);
(3)引數指標本身為常量不可變(也無意義,因為char* var也是形參)
void function(char* const var);
(4)引數為引用,為了增加效率同時防止修改。修飾引用引數時:
void function(const class& var); //引用引數在函式內不可以改變
void function(const type& var); //引用引數在函式內為常量不可變
當輸入引數為使用者自定義型別和抽象資料型別時,將「值傳遞」改為「const&傳遞」可以提高效率,可以比較如下的**:
void fun(a a);
void fun(a const& a);
第乙個函式效率較低,函式體內產生a型別的臨時物件用於「值傳遞」引數a,而臨時物件的構造、複製、析構過程都需要消耗資源和時間的,但使用第二種方式,按「引用傳遞」不需要產生臨時物件,省了臨時物件的構造、複製、析構的過程,因此效率較高。而之所以用const修飾a,是為了保證引用a不被修改。
(二)const修飾函式返回值
(1)函式按const指標
返回,表示該指標不能被改動,只能把該指標賦給const修飾的同型別指標變數。
const char *getchar(void){};
char*ch=getchar();//錯誤,按指標返回時,該函式返回值只能被賦值給const修飾的同型別指標
const char *ch=getchar();//正確
(2)函式按值返回,函式會把返回值賦給外部臨時變數,用const無意義!不管是內部還是非內部資料型別。
int const get()
int temp=i.get();//正確,按值傳遞時,接受返回值有無const均可
(3)函式採用引用方式返回的場合不多,只出現在類的賦值函式中,目的是為了實現鏈式表達。
(三)const修飾類的成員函式(函式定義體):
通常,任何不需要修改資料成員的函式都應該宣告為const型別,這樣,如果const成員函式修改了資料成員或者呼叫了其他函式修改資料成員,編譯器都將報錯!
class stack
;int stack::getcount(void) const
編譯器輸出錯誤資訊:error c2166: l-value specifies const object。
例題:給定宣告 const char * const * pp; 下列操作或說明正確的是?
a.pp++
b.(*pp)++
c.(**pp) = \\c\\;
d.以上都不對
正確答案: a
【詳細解釋】
:const 限定乙個物件為唯讀屬性。
分析的原則:
char const *ptr:若const限定符在*之前,則const限定的是*ptr。也就是說,ptr可以改變其所指向的物件,但不能通過該指標修改其所指向物件的值。若const限定符在*之後,則const限定的是ptr而不限定*ptr。也就是說,ptr不可以改變其所指向的物件,但能通過該指標修改其所指向物件的值。
若在*之前有const限定符且在*之後也有const限定符,則ptr與*ptr都被限定。也就是說,ptr既不可以改變其所指向的物件,也不能通過該指標修改其所指向物件的值。
先從一級指標說起吧:
(1)const char p //限定變數p為唯讀。這樣如p=2這樣的賦值操作就是錯誤的。
(2)const char *p //p為乙個指向char型別的指標,const只限定p指向的物件為唯讀。這樣,p=&a或 p++等操作都是合法的,但如*p=4這樣的操作就錯了,因為企圖改寫這個已經被限定為唯讀屬性的物件。 (const 限定*p,即限定p指向的內容)
(3)char *const p 限定此指標為唯讀,這樣p=&a或 p++等操作都是不合法的。而*p=3這樣的操作合法,因為並沒有限定其最終物件為唯讀。 (const直接與p結合,因此這裡只限定了指標本身p,但內容可以修改 )
(4)const char *const p 兩者皆限定為唯讀,不能改寫。 (結合方向:const char *(const p))
有了以上的對比,再來看二級指標問題:
(1)const char **p p為乙個指向指標的指標,const限定其最終物件為唯讀,顯然這最終物件也是為char型別的變數。故像**p=3這樣的賦值是錯誤的,而像*p=? p++這樣的操作合法。
(2)const char * const *p 限定最終物件和 p指向的指標為唯讀。這樣 *p=?的操作也是錯的。
(3)const char * const * const p 全部限定為唯讀,都不可以改寫。
C C 中的關鍵字 static 和const
靜態變數具有記憶功能,這次的值是上次修改的值,所以只能被初始化一次 儲存在靜態區的變數生命週期一般比較長,同 整個源程式共存亡,所以只需初始化一次 分為靜態全域性變數和靜態區域性變數 靜態全域性變數只在定義它的原始檔內有效,其他原始檔無法訪問它 靜態區域性變數 儲存在全域性儲存區,雖然是區域性的 只...
C C 關鍵字 static 和 const
參考 1.靜態全域性變數和函式 靜態全域性變數 static a 靜態函式 static void myfunc 2.靜態區域性變數 靜態區域性變數 每次呼叫該函式a都會加1,不會被重新初始化為0。void myfunc 3.靜態類成員變數和函式 類 class myclass 定義並初始化靜態成員...
c c 中static和extern使用
在c c 中static和extern都能夠用來修飾函式和變數,可是是有差別的。內部函式和內部變數 僅僅能在檔案內使用的函式和變數。外部函式和外部變數 可以被其他檔案使用的函式和變數。static 1 對函式 定義乙個內部函式 static void test 宣告乙個內部函式 static voi...