中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
【轉(zhuǎn)】C/c++關(guān)于const關(guān)鍵字的用法
                     C語言與C++中的const關(guān)鍵字
 1.   const in c language
          

關(guān)于C的關(guān)鍵字——const的理解和用法

const在C中的用法很靈活(相信C++中也一樣),個人感覺對之既愛又恨,有時候感覺const很好用,同時又經(jīng)

常會因為它的優(yōu)點而犯錯,犯錯的原因除了粗心之外,另一個更重要的,就是以前對const理解不到位。于是今天

自己寫成一篇小總結(jié)。如果是初學(xué)者,建議好好看一下,相信幫助比較大;如果是高手,請不吝賜教!

    上面寫了一段廢話,就算是小序吧:)接下來就是正文;

    一、關(guān)于const的具體定義:

       ——個人感覺很難對它下一個標(biāo)準(zhǔn)的定義,因為的用法很靈活,似乎對它定義后總無法讓人能夠明白它的

意思,而且容易讓人產(chǎn)生誤解(也許是偶水平太菜了)。例如,把它有定義:一個能夠讓變量變成無法修改的常量

的關(guān)鍵字。那么,這樣的話,就可能讓人誤解為只要有const在定義變量里面,那變量就無論怎樣都無法修改。這

樣的理解是很片面的(下面用法方面將對這問題做探討)。因此,本人在此不敢對它下定義,其他參考書好象也沒

有下定義。

    二、關(guān)于const的具體作用
        ——const作用就靈活了,一個表達式中const放置的位置不同,效果可能就不一樣了。下面分具體情況分

析(當(dāng)然,所舉的情況并非覆蓋全部情況)
        A。const最經(jīng)常的用法
           1.為了防止傳遞的函數(shù)參數(shù)不被修改,在調(diào)用函數(shù)的形參中用const關(guān)鍵字.
               //Example ->

               int FindNum(const int array[], int num, int conut);//聲明函數(shù)

               //code...

               int FindNum(const int array[], int num, int count)
               {
                          int i;
                          int flag = 1;

                          for (i = 0; (i < count) && flag; i++)
                          {
                                   if (array[i] == num)
                                   {
                                           flag = 0;
                                           break;
                                   }
                           }
                           return flag;
                }
                //code...
                
           上面這例子中,編譯器會把array[]當(dāng)作常量數(shù)據(jù)的數(shù)組看待。所以,假如你不小心給數(shù)組賦值,那么

,編譯器就會報錯了。因此,當(dāng)你不需要也不想修改數(shù)組的數(shù)據(jù)時,最好用const把數(shù)組定義為常量數(shù)組。

           2.const可以用來創(chuàng)建數(shù)組常量、指針常量、指向常量的指針等:
             const char ch = 'a';
             const int a[5] = {1, 2, 3, 4, 5};  
             const int *p = a;              //a是一個數(shù)組的首地址.p是指向常量的指針
             int * const p = a;             //a是一個數(shù)組的首地址.p是指針常量;
             const int * const p = a;    //a是一個數(shù)組的首地址。p是指向常量的指針常量

             前兩種情況很簡單,現(xiàn)在著重分析一下后三種用法,因為這3種情況容易出錯,偶就有時候怕用錯了

剛脆不用const.

             ——const int *p = a;       //p是指向常量的指針,因此,不可以通過給指針賦值來改變數(shù)組

                                                   //中的數(shù)據(jù),例如:
                                                   // *p = 10;       /*錯誤*/
                                                   // *(p + 2) = 1;  /*錯誤*/

                                                   //假如指向常量指針可以改變值,那么,就等于也改變了數(shù)組的數(shù)  

                                                   //據(jù)了。假如你不理解,偶倒有一個辦法讓你理解,你就想你和一  

                                                   //個人綁在一起,有可能你移動了位置而他不跟著你移動嗎!哈哈

             ——int * const p = a;       //看這表達式,const的位置和第一個不同吧!他們的用法和作用  

                                                    //就完全不一樣了。這時候p是指針常量,我們知道,指針是指向  

                                                    //了一個數(shù)組的首地址,那么,它的位置就不可以改變了。但是你  

                                                   //現(xiàn)在應(yīng)該和第一個表達式比較了,現(xiàn)在的數(shù)組并不是常量數(shù)組,  

                                                   //所以數(shù)組的數(shù)據(jù)是可以改變的,而指針這時候它是不可以移動的  

                                                   //,指向數(shù)組第一個數(shù)據(jù),所以它可以而且只可以改變數(shù)組第一個  

                                                  //數(shù)據(jù)的值。這一點請別誤解,指針常量只是它的地址不可以改變  

                                                  //,并不是它指向的內(nèi)容一定不可以改變,這一點切記!

                                                  //好啦。假如你又不理解,偶又有一個比較形象的例子來說明:

                                                  //假如有一個固定的人拉著另外一個人的手,注意,固定的人相當(dāng)  

                                                   //于他是不可以由其他人來替換的。但是他可以拉其他人的手啊,  

                                                  //并不一定規(guī)定他必須拉同一個人的手啊。現(xiàn)在你應(yīng)該可以有個比  

                                                  //較深的印象和理解吧:P

                                                  //下面舉幾個例子幫助理解:
                                                  //  *p = 2;          /*可以*/
                                                 //  *(p+1) = 10;     /*可以*/
                                                 //  p++;             /*不可以*/

            ——const int * const p = a; //假如前面兩種表達式的本質(zhì)你理解了,這種表達式你來理解根本

                                         //沒有問題,const現(xiàn)在有兩個,而且一個const的位置是第一種情  

                                         //況的位置,第二個const是第二種情況的位置,所以這表達式的功  

                                         //能就是前兩種情況的作用總合。這里不多說!

                                         //下面舉幾個例子幫助理解:
                                         //  *p = 2;             /*不可以*/
                                         //  *(p + 2) = 10;   /*不可以*/
                                         //  p++;                /*不可以*/

        B。const并不會阻止參數(shù)的修改

           之所以把這作為一點來談,就是因為有一些朋友可能會以為在函數(shù)參數(shù)中用了const就一定不可以改變

參數(shù),這實際上是錯誤的理解,因為,它并不阻止參數(shù)的修改,下面舉個簡單的例子來闡述一下;

           #include
           #include
          
           void ChangeStr(const char *String);
  
           int main(void)
           {
                    char str[] = "The C programme";

                    Change(str);
                    printf(str);
                    
                    system("Pause");
                    return 0;
            }

            void ChangeStr(const char *String)
            {
                    char *Source = (char *)String;
              
                    while (*Source)
                    {
                               *Source = toupper(*Source);
                               Source++;
                    }
             }

             //end

             上面的程序把字符串中的每個字符都轉(zhuǎn)換成大寫字母了。因為*String把地址給了*Source,而

*Source的值的改變編譯器并不干涉,可能有的編譯器會發(fā)出警告之類。上面的程序只是為了說明const并不會阻止

參數(shù)的修改,如果象上面程序那樣,個人感覺沒什么意義,只會讓人容易混亂而已。

        關(guān)于CONST的用法和理解本人也就只能說這么多了,當(dāng)然,很可能有更多高級或者少用的用法,由于水平

和經(jīng)驗有限,確實不能再說些什么。

  三、參考文獻
      ——《C primer plus 5th》    

                                                                              ID: lj_860603
                                                                            整理于2006.5.21

 

2. const in c++ language

面向?qū)ο笫荂++的重要特性.

但是c++在c的基礎(chǔ)上新增加的幾點優(yōu)化也是很耀眼的

就const直接可以取代c中的#define

以下幾點很重要,學(xué)不好后果也也很嚴(yán)重

 

const
1. 限定符聲明變量只能被讀
   const int i=5;
   int j=0;
   ...
   i=j;   //非法,導(dǎo)致編譯錯誤
   j=i;   //合法
2. 必須初始化
   const int i=5;    //合法
   const int j;      //非法,導(dǎo)致編譯錯誤
3. 在另一連接文件中引用const常量
   extern const int i;     //合法
   extern const int j=10;  //非法,常量不可以被再次賦值
4. 便于進行類型檢查
   用const方法可以使編譯器對處理內(nèi)容有更多了解。
   #define I=10
   const long &i=10;   /*dapingguo提醒:由于編譯器的優(yōu)化,使
      得在const long i=10; 時i不被分配內(nèi)存,而是已10直接代入
      以后的引用中,以致在以后的代碼中沒有錯誤,為達到說教效
      果,特別地用&i明確地給出了i的內(nèi)存分配。不過一旦你關(guān)閉所
      有優(yōu)化措施,即使const long i=10;也會引起后面的編譯錯誤。*/
   char h=I;      //沒有錯
   char h=i;      //編譯警告,可能由于數(shù)的截短帶來錯誤賦值。
5. 可以避免不必要的內(nèi)存分配
   #define STRING "abcdefghijklmn\n"
   const char string[]="abcdefghijklm\n";
   ...
   printf(STRING);   //為STRING分配了第一次內(nèi)存
   printf(string);   //為string一次分配了內(nèi)存,以后不再分配
   ...
   printf(STRING);   //為STRING分配了第二次內(nèi)存
   printf(string);
   ...
   由于const定義常量從匯編的角度來看,只是給出了對應(yīng)的內(nèi)存地址,
   而不是象#define一樣給出的是立即數(shù),所以,const定義的常量在
   程序運行過程中只有一份拷貝,而#define定義的常量在內(nèi)存中有
   若干個拷貝。
6. 可以通過函數(shù)對常量進行初始化
   int value();
   const int i=value();
   dapingguo說:假定對ROM編寫程序時,由于目標(biāo)代碼的不可改寫,
   本語句將會無效,不過可以變通一下:
   const int &i=value();
   只要令i的地址處于ROM之外,即可實現(xiàn):i通過函數(shù)初始化,而其
   值有不會被修改。
7. 是不是const的常量值一定不可以被修改呢?
   觀察以下一段代碼:
   const int i=0;
   int *p=(int*)&i;
   p=100;
   通過強制類型轉(zhuǎn)換,將地址賦給變量,再作修改即可以改變const常量值。
8. 請分清數(shù)值常量和指針常量,以下聲明頗為玩味:
   int ii=0;
   const int i=0;            //i是常量,i的值不會被修改
   const int *p1i=&i;        //指針p1i所指內(nèi)容是常量,可以不初始化
   int  * const p2i=?     //指針p2i是常量,所指內(nèi)容可修改
   const int * const p3i=&i; //指針p3i是常量,所指內(nèi)容也是常量
   p1i=?                  //合法
   *p2i=100;                 //合法

關(guān)于C++中的const關(guān)鍵字的用法非常靈活,而使用const將大大改善程序的健壯性,參考了康建東兄的const使用詳解一文,對其中進行了一些補充,寫下了本文。

 

 


1.       const常量,如const int max = 100; 
優(yōu)點:const常量有數(shù)據(jù)類型,而宏常量沒有數(shù)據(jù)類型。編譯器可以對前者進行類型安全檢查,而對后者只進行字符替換,沒有類型安全檢查,并且在字符替換時可能會產(chǎn)生意料不到的錯誤(邊際效應(yīng))


2.       const 修飾類的數(shù)據(jù)成員。如:
class A


{


    const int size;


    …


}


const數(shù)據(jù)成員只在某個對象生存期內(nèi)是常量,而對于整個類而言卻是可變的。因為類可以創(chuàng)建多個對象,不同的對象其const數(shù)據(jù)成員的值可以不同。所以不能在類聲明中初始化const數(shù)據(jù)成員,因為類的對象未被創(chuàng)建時,編譯器不知道const 數(shù)據(jù)成員的值是什么。如


class A


{


 const int size = 100;    //錯誤


 int array[size];         //錯誤,未知的size


}


const數(shù)據(jù)成員的初始化只能在類的構(gòu)造函數(shù)的初始化表中進行。要想建立在整個類中都恒定的常量,應(yīng)該用類中的枚舉常量來實現(xiàn)。如


class A


{…


 enum {size1=100, size2 = 200 };


int array1[size1];


int array2[size2];


}


枚舉常量不會占用對象的存儲空間,他們在編譯時被全部求值。但是枚舉常量的隱含數(shù)據(jù)類型是整數(shù),其最大值有限,且不能表示浮點數(shù)。


3.       const修飾指針的情況,見下式:


int b = 500;
const int* a = &           [1]
int const *a = &           [2]
int* const a = &           [3]
const int* const a = &     [4]

如果你能區(qū)分出上述四種情況,那么,恭喜你,你已經(jīng)邁出了可喜的一步。不知道,也沒關(guān)系,我們可以參考《Effective c++》Item21上的做法,如果const位于星號的左側(cè),則const就是用來修飾指針?biāo)赶虻淖兞浚粗羔樦赶驗槌A?;如果const位于星號的右側(cè),const就是修飾指針本身,即指針本身是常量。因此,[1]和[2]的情況相同,都是指針?biāo)赶虻膬?nèi)容為常量(const放在變量聲明符的位置無關(guān)),這種情況下不允許對內(nèi)容進行更改操作,如不能*a = 3 ;[3]為指針本身是常量,而指針?biāo)赶虻膬?nèi)容不是常量,這種情況下不能對指針本身進行更改操作,如a++是錯誤的;[4]為指針本身和指向的內(nèi)容均為常量。


4.     const的初始化

先看一下const變量初始化的情況
1) 非指針const常量初始化的情況:A b;
const A a = b;

2) 指針const常量初始化的情況:


A* d = new A();
const A* c = d;
或者:const A* c = new A();
3)引用const常量初始化的情況:
A f;
const A& e = f;      // 這樣作e只能訪問聲明為const的函數(shù),而不能訪問一           


般的成員函數(shù);

    [思考1]: 以下的這種賦值方法正確嗎?
    const A* c=new A();
    A* e = c;
    [思考2]: 以下的這種賦值方法正確嗎?
    A* const c = new A();
    A* b = c;


5.     另外const 的一些強大的功能在于它在函數(shù)聲明中的應(yīng)用。在一個函數(shù)聲明中,const 可以修飾函數(shù)的返回值,或某個參數(shù);對于成員函數(shù),還可以修飾是整個函數(shù)。有如下幾種情況,以下會逐漸的說明用法:A& operator=(const A& a);
void fun0(const A* a );
void fun1( ) const; // fun1( ) 為類成員函數(shù)
const A fun2( );


1) 修飾參數(shù)的const,如 void fun0(const A* a ); void fun1(const A& a);
調(diào)用函數(shù)的時候,用相應(yīng)的變量初始化const常量,則在函數(shù)體中,按照const所修飾的部分進行常量化,如形參為const A* a,則不能對傳遞進來的指針的內(nèi)容進行改變,保護了原指針?biāo)赶虻膬?nèi)容;如形參為const A& a,則不能對傳遞進來的引用對象進行改變,保護了原對象的屬性。
[注意]:參數(shù)const通常用于參數(shù)為指針或引用的情況,且只能修飾輸入?yún)?shù);若輸入?yún)?shù)采用“值傳遞”方式,由于函數(shù)將自動產(chǎn)生臨時變量用于復(fù)制該參數(shù),該參數(shù)本就不需要保護,所以不用const修飾。


[總結(jié)]對于非內(nèi)部數(shù)據(jù)類型的輸入?yún)?shù),因該將“值傳遞”的方式改為“const引用傳遞”,目的是為了提高效率。例如,將void Func(A a)改為void Func(const A &a)


      對于內(nèi)部數(shù)據(jù)類型的輸入?yún)?shù),不要將“值傳遞”的方式改為“const引用傳遞”。否則既達不到提高效率的目的,又降低了函數(shù)的可理解性。例如void Func(int x)不應(yīng)該改為void Func(const int &x)


2)  修飾返回值的const,如const A fun2( ); const A* fun3( );
這樣聲明了返回值后,const按照"修飾原則"進行修飾,起到相應(yīng)的保護作用。const Rational operator*(const Rational& lhs, const Rational& rhs)
{
return Rational(lhs.numerator() * rhs.numerator(),
lhs.denominator() * rhs.denominator());
}

返回值用const修飾可以防止允許這樣的操作發(fā)生:Rational a,b;
Radional c;
(a*b) = c;

一般用const修飾返回值為對象本身(非引用和指針)的情況多用于二目操作符重載函數(shù)并產(chǎn)生新對象的時候。
[總結(jié)]


1.     一般情況下,函數(shù)的返回值為某個對象時,如果將其聲明為const時,多用于操作符的重載。通常,不建議用const修飾函數(shù)的返回值類型為某個對象或?qū)δ硞€對象引用的情況。原因如下:如果返回值為某個對象為const(const A test = A 實例)或某個對象的引用為const(const A& test = A實例) ,則返回值具有const屬性,則返回實例只能訪問類A中的公有(保護)數(shù)據(jù)成員和const成員函數(shù),并且不允許對其進行賦值操作,這在一般情況下很少用到。


2.       如果給采用“指針傳遞”方式的函數(shù)返回值加const修飾,那么函數(shù)返回值(即指針)的內(nèi)容不能被修改,該返回值只能被賦給加const 修飾的同類型指針。如:


const char * GetString(void);


如下語句將出現(xiàn)編譯錯誤:


char *str=GetString();


正確的用法是:


const char *str=GetString();


3.     函數(shù)返回值采用“引用傳遞”的場合不多,這種方式一般只出現(xiàn)在類的賻值函數(shù)中,目的是為了實現(xiàn)鏈?zhǔn)奖磉_。如:


class A


{…


 A &operate = (const A &other);  //負值函數(shù)


}
A a,b,c;              //a,b,c為A的對象



a=b=c;            //正常


(a=b)=c;          //不正常,但是合法


若負值函數(shù)的返回值加const修飾,那么該返回值的內(nèi)容不允許修改,上例中a=b=c依然正確。(a=b)=c就不正確了。
[思考3]: 這樣定義賦值操作符重載函數(shù)可以嗎?
const A& operator=(const A& a);


6.     類成員函數(shù)中const的使用
一般放在函數(shù)體后,形如:void fun() const;
任何不會修改數(shù)據(jù)成員的函數(shù)都因該聲明為const類型。如果在編寫const成員函數(shù)時,不慎修改了數(shù)據(jù)成員,或者調(diào)用了其他非const成員函數(shù),編譯器將報錯,這大大提高了程序的健壯性。如:


class Stack


{


 public:


      void Push(int elem);


      int Pop(void);


      int GetCount(void) const;   //const 成員函數(shù)


 private:


      int m_num;


      int m_data[100];


};


int Stack::GetCount(void) const


{


  ++m_num;              //編譯錯誤,企圖修改數(shù)據(jù)成員m_num


  Pop();                    //編譯錯誤,企圖調(diào)用非const函數(shù)


  Return m_num;


}


7.       使用const的一些建議

1 要大膽的使用const,這將給你帶來無盡的益處,但前提是你必須搞清楚原委;
2 要避免最一般的賦值操作錯誤,如將const變量賦值,具體可見思考題;
3 在參數(shù)中使用const應(yīng)該使用引用或指針,而不是一般的對象實例,原因同上;
4 const在成員函數(shù)中的三種用法(參數(shù)、返回值、函數(shù))要很好的使用;
5 不要輕易的將函數(shù)的返回值類型定為const;
6除了重載操作符外一般不要將返回值類型定為對某個對象的const引用;

[思考題答案]
1 這種方法不正確,因為聲明指針的目的是為了對其指向的內(nèi)容進行改變,而聲明的指針e指向的是一個常量,所以不正確;
2 這種方法正確,因為聲明指針?biāo)赶虻膬?nèi)容可變;
3 這種做法不正確;
在const A::operator=(const A& a)中,參數(shù)列表中的const的用法正確,而當(dāng)這樣連續(xù)賦值的時侯,問題就出現(xiàn)了:
A a,b,c:
(a=b)=c;
因為a.operator=(b)的返回值是對a的const引用,不能再將c賦值給const常量。

編輯 webmaster

3.const 深度解析

我們也許學(xué)習(xí)過const的使用,但是對于const的細致的技術(shù)細節(jié)卻不一定掌握。const的用法在許多的教材上只是簡單的介紹,在這里我們對 const進行細致的概念以及用法剖析。const 是由c++采用,并加進標(biāo)準(zhǔn)c中,但是他們的意義完全不同,在舊版本(標(biāo)準(zhǔn)前)的c中,如果想建立一個常量,必須使用預(yù)處理器:
#define PI 3.14159

此后無論在何處使用PI,都會被預(yù)處理器以3.14159替代。編譯器不對PI進行類型檢查,也就是說可以不受限制的建立宏并用它來替代值,如果使用不慎,很可能由預(yù)處理引入錯誤,這些錯誤往往很難發(fā)現(xiàn)。

我們也不能得到PI的地址(即不能向PI傳遞指針和引用)。
c++引入了命名常量的概念,命名常量就像變量一樣,只是它的值不能改變,如果試圖改變一個const 對象,編譯器將會產(chǎn)生錯誤。 const 和正常變量一樣有作用域,所以函數(shù)內(nèi)部的const也不會影響程序的其余部分。在c++中const可以取代預(yù)處理器#define來進行值替代, const有安全的類型檢查,所以不用擔(dān)心會像預(yù)處理器一樣引入錯誤。

在通常的情況下const同預(yù)處理器#define一樣只是將所賦值保存入編譯器的符號表中(符號表僅僅在編譯時存在,在編譯過程中編譯器將程序中的名字與之在符號表中定義的數(shù)值作簡單的替換),在使用的時候進行值替換,并不為const創(chuàng)建存儲空間。我們將const的定義放進頭文件里,這樣通過包含頭文件,可以把const定義單獨放在一個地方并把它分配給一個編譯單元,const默認為內(nèi)部連接(內(nèi)部連接意味著只對正在編譯的文件創(chuàng)建存儲空間,別的文件可以使用相同的標(biāo)示符和全局變量,編譯器不會發(fā)現(xiàn)沖突,外部連接意味著為所有被編譯過的文件創(chuàng)建一片單獨的存儲空間,一般全局變量和函數(shù)名的外部連接通過extern聲明,可以通過其他的文件訪問)也就是說const僅能被它所定義過的文件訪問,在定義一個const時,必須賦一個值給它,除非用extern做出說明:

extern const int a;

這表示const的定義在其他的什么地方,這里僅僅是一個聲明,但是這樣的做法使const使用了外部連接,也就是說上面的extern強制進行了對const的存儲空間分配,這樣我們就無法再用const作為常量折疊(在可能的情況下,符號常量的值會代替改名字的出現(xiàn),這個替代過程叫做常量折疊)使用了,即使我們在其他地方定義了const的值,如:

extern const int a=3;

因為const的值被放入了存儲單元,在編譯的過程中,編譯器不會去讀存儲單元的內(nèi)容。如果我們這樣做:

int b[a];

編譯器就會給我們一個錯誤信息。

想不為const分配存儲空間是不可能的,因為對于復(fù)雜的結(jié)構(gòu),例如集合,編譯器不會復(fù)雜到將集合保存到它的符號表中,所以必須分配內(nèi)存空間,這就意味著“這是一塊不能改變的存儲空間”,當(dāng)然也就不能在編譯期間使用它的值,因為編譯器不知道存儲的內(nèi)容:

const int i[]={1,2,3,4};

//float f[i[2]];
//將得到錯誤信息,編譯器提示不能在數(shù)組定義里找到一個常數(shù)表達式。

因為編譯器靠移動棧指針來存儲和讀取數(shù)據(jù)。
也因此,由于無法避免為const分配內(nèi)存,所以const的定義必須默認為內(nèi)部連接,否則由于眾多的const在多個文件中分配內(nèi)存,就會引起錯誤。下面我們看一段簡單有效的代碼來說明const的常量折疊:

#include
const int a=3;
const int b=a+1;
float *f=(float*)&b;
char c[b+3];
void main()
{
const char gc=cin.get();
const char c2=gc+3;
}

我們可以看到,a是一個編譯器期間的const,b是從a中計算出來的,由于a是一個const,b的計算值來自一個常數(shù)表達式,而它自身也是一個編譯器間的const,接著下面指針f取得了b的地址,所以迫使編譯器給b分配了存儲空間,不過即使分配了存儲空間,由于編譯器已經(jīng)知道了b的值,所以仍然不妨礙在決定數(shù)組c的大小時使用b。

在主函數(shù)main()里,標(biāo)識符gc的值在編譯期間是不知道的,這也意味著需要存儲空間,但是初始化要在定義點進行,而且一旦初始化,其值就不能改變,我們發(fā)現(xiàn)c2是由gc計算出來的,它的作用域與其他類型const的作用域是一樣的,這是對#define用法的一種改進。

在c++引進常量的時候,標(biāo)準(zhǔn)c也引入了const,但是在c中const的意思和在c++中有很大不同,在c中const的意思是“一個不能改變的普通變量”,const常量總是被分配存儲空間而且它的名字是全局符即const使用外部連接。于是在c中:

const int size=100;
char c[size];

得出一個錯誤。但是在c中可以這樣寫:

const int size;

因為c中的const被默認為外部連接,所以這樣做是合理的。
在c語言中使用限定符const不是很有用,如果希望在常數(shù)表達式里(必須在編譯期間被求值)使用一個已命名的值,必須使用預(yù)處理器#define。

在c++中可以使指針成為const,這很有用,如果以后想在程序代碼中改變const這種指針的使用,編譯器將給出通知,這樣大大提高了安全性。在用帶有const的指針時,我們有兩種選擇:const修飾指針指向的對象,或者const修飾指針自己指向的存儲空間。

如果要使指向的對象不發(fā)生改變,則需要這樣寫:

const int *p;

這里p是一個指向const int 的指針,它不需要初始化,因為p可以指向任何標(biāo)識符,它自己并不是一個const,但是它所指的值是不能改變的,同樣的,我們可以這樣寫:

int const *p;

這兩種方法是等同的,依據(jù)個人習(xí)慣以及編碼風(fēng)格不同,程序員自己決定使用哪一種形式。
如果希望使指針成為一個const必須將const標(biāo)明的部分放在*右邊。

int a=3;
int *const j=&a

編譯器要求給它一個初始值,這個值在指針的生命期間內(nèi)不變,也就是說指針始終指向a的地址,不過要改變它地址中的值是可以的:

*j+=4;

也可以是一個const指針指向一個const對象:

const int *j1=&a;
int const *j2=&a;

這樣指針和對象都不能改變,這兩種形式同樣是等同的。在賦值的的時候需要注意,我們可以將一個非const的對象地址賦給一個const指針,但是不能將一個const對象地址賦給一個非const指針,因為這樣可能通過被賦值的指針改變對象的值,當(dāng)然也可以用類型的強制轉(zhuǎn)換來進行const對象的賦值,但是這樣做打破了const提供的安全性。

const也被用于限定函數(shù)參數(shù)和函數(shù)的返回值,如果函數(shù)參數(shù)是按值傳遞時,即表示變量的初值不會被函數(shù)改變,如果函數(shù)的返回值為const那么對于內(nèi)部類型來說按值返回的是否是一個cosnt是無關(guān)緊要的,編譯器不讓它成為一個左值,因為它是一個值而不是一個變量,所以使用const是多余的,例如:

const int f(){return 1;}
void main(){int a=f();}

但是當(dāng)處理用戶定義類型的時候,按值返回常量就很有意義了,這時候函數(shù)的返回值不能被直接賦值也不能被修改。僅僅是非const返回值能作為一個左值使用,但是這往往失去意義,因為函數(shù)返回值在使用時通常保存為一個臨時量,臨時量被作為左值使用并修改后,編譯器將臨時量清除。結(jié)果丟失了所有的修改。
可以用const限定傳遞或返回一個地址(即一個指針或一個引用):

const int * const func(const int *p)
{ static int a=*p;
return &a;
}

參數(shù)內(nèi)的const限定指針p指向的數(shù)據(jù)不能被改變,此后p的值被賦給靜態(tài)變量a,然后將a的地址返回,這里a是一個靜態(tài)變量,在函數(shù)運行結(jié)束后,它的生命期并沒有結(jié)束,所以可以將它的地址返回。因為函數(shù)返回一個const int* 型,所以函數(shù)func的返回值不可以賦給一個非指向const的指針,但它同時接受一個const int * const和一個const int *指針,這是因為在函數(shù)返回時產(chǎn)生一個const臨時指針用以存放a的地址,所以自動產(chǎn)生了這種原始變量不能被改變的約定,于是*右邊的const只有當(dāng)作左值使用時才有意義。

const同樣運用于類中,但是它的意義又有所不同,我們可以創(chuàng)建const的數(shù)據(jù)成員,const的成員函數(shù),甚至是const的對象,但是保持類的對象為const比較復(fù)雜,所以const對象只能調(diào)用const成員函數(shù)。

const的數(shù)據(jù)成員在類的每一個對象中分配存儲,并且一旦初始化這個值在對象的生命期內(nèi)是一個常量,因此在類中建立一個const數(shù)據(jù)成員時,初始化工作必須在構(gòu)造函數(shù)初始化列表中。如果我們希望創(chuàng)建一個有編譯期間的常量成員,這就需要在該常量成員的前面使用static限定符,這樣所有的對象都僅有一個實例:

class X
{
static const int size=50;
int a[size];
public:
X();
};

const對象只能調(diào)用const成員函數(shù),一個普通對象同樣可以調(diào)用const成員函數(shù),因此,const成員函數(shù)更具有一般性,但是成員函數(shù)不會默認為const。聲明一個const成員函數(shù),需要將const限定符放在函數(shù)名的后面:

void f (void ) const;

當(dāng)我們運用const成員函數(shù)時,遇到需要改變數(shù)據(jù)成員,可以用mutable進行特別的指定:

class X
{
mutable int i;
public:
X();
void nochange() const;
};

void X::nochange const(){i++;}

const消除了預(yù)處理器的值替代的不良影響,并且提供了良好的類型檢查形式和安全性,在可能的地方盡可能的使用const對我們的編程有很大的幫助。 
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
C++ 學(xué)習(xí)要點
C++中const用法總結(jié)
const關(guān)鍵字(二)
C/C :基本語法看這一篇就夠了
C++ const用法 盡可能使用const
再談指針:大佬給你撥開 C指針 的云霧
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服