C/C++中Static和Const的作用

pan_jinquan發表於2016-11-15

 C/C++中Static和Const的作用

    【尊重原創,轉載請註明出處】http://blog.csdn.net/guyuealian/article/details/53118850
一、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(){return this->n;}
int temp=i.get();//正確,按值傳遞時,接受返回值有無const均可
  (3)函式採用引用方式返回的場合不多,只出現在類的賦值函式中,目的是為了實現鏈式表達。
  (三)const修飾類的成員函式(函式定義體):
    通常,任何不需要修改資料成員的函式都應該宣告為const型別,這樣,如果const成員函式修改了資料成員或者呼叫了其他函式修改資料成員,編譯器都將報錯!
class stack
{
public:
	int GetCount(void) const ;
private:
	int m_num;
};
int stack::GetCount(void) const
{
	m_num++;
}
編譯器輸出錯誤資訊: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 全部限定為只讀,都不可以改寫。


相關文章