CONST,STATIC,EXTERN用法總結!

來源:互聯網
上載者:User

最近看許多公司筆試都考這幾方面的內容,於是乎就搜尋了一下,把這幾個知識點總結以下,以增強基礎,以及應付未來的筆試

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

--------------------------CONST---------------------------------------
const應用:
一、對於基本聲明
    const int r=100;//標準const變數聲明加初始化,編譯器經過類型檢查後直接用100在編譯時間替換。
二、對於指標
    1. int x=10; const int *r=&x; //指標指向的內容是常量,r指向的內容不能夠通過r改變,但如果是非const,內容可以通過自己改變,而且r指標可以改變,可以指向其它的整形.

    //*r=*r+1;NO //x++;YES //r=&y;YES
    2. int const *r=&x; 與1完全相同
    3. int * const r=&x; //指標指向是常量,不能修改去指向其它內容,但指向的內容可以修改
     //r=&y;NO //*r=*r+1;YES //x++;YES
    4.const int * const r=&x; //綜合1、3用法,r是一個指向常量的常量型指標,指標指向不能改變,指標內容不能改變,內容可以自身改變

    //r=&y;NO //*r=*r+1;NO //x++;YES

三、對於類型檢查
    可以把非const對象賦予const指標,這樣就不能改變.但是不能把const賦給非const,除非先強制轉換
const int x=100; int *p=(int*)&x; *p++;
四、對於函數
    1.void Fuction1(const int r); //此處為參數傳遞const值,意義是變數初值不能被函數改變
    2.const int Fuction1 (int); //此處返回const值,意思指返回的原函數裡的變數的初值不能被修改,但是函數按值返回的這個變數被製成副本,能不能被修改就沒有了意義,它可以被賦給任何的const或非const類型變數,完全不需要加上這個const關鍵字。
    3.Class CX; //內部有建構函式,聲明如CX(int r =0)
      CX Fuction1 () { return CX(); }
      const CX Fuction2 () { return CX(); }
      Fuction1() = CX(1); //沒有問題,可以作為左值調用
      Fuction2() = CX(1); //編譯錯誤,const傳回值禁止作為左值調用。
    4.函數中指標的const傳遞和返回:
    int F1 (const char *pstr); //作為傳遞的時候使用const修飾可以保證不會通過這個指標來修改傳遞參數的初值
    const char *F2();//意義是函數返回的指標指向的對象是一個const對象,它必須賦給一個同樣是指向const對象的指標
    const char * const F3(); //比上面多了一個const,這個const的意義只是在他被用作左值時有效,它表明了這個指標除了指向const對象外,它本身也不能被修改,所以就不能當作左值來處理。

五、對於類
    1.首先,對於const的成員變數,只能在建構函式裡使用初始化成員列表來初始化,試圖在建構函式體內進行初始化const成員變數會引起編譯錯誤。初始化成員列表形如:
   X:: X ( int ir ): r(ir) {} //假設r是類X的const成員變數
      注意:類的構造和解構函式都不能是const函數。
    2.建立了一個const成員函數,但仍然想用這個函數改變對象內部的資料。(函數不能修改類的資料成員)
//假如有一個叫做X的類,它有一個int成員變數r,我們需要通過一個const成員函數f( )來對這個r進行++r操作,代碼如下
void X::f( ) const
{ (const_cast(this)) -> ++r; } //通過this指標進行類型強制轉換實現

--------------------------------STATIC--------------------------------
對於一個完整的程式,記憶體中的分布情況:
      ==========
      |      代碼區    |
      ------------------
      | 全域資料區  |
      ------------------
      |       堆區       |
      -----------------
      |        棧區      |
      ==========
    一般程式的由new產生的動態資料存放在堆區,函數內部的自動變數存放在棧區,全域變數和static變數放在全域資料區

static的作用主要有以下3個:
    1、擴充生存期;
    2、限制範圍;
    3、唯一性

STATIC:

一、面向過程設計中的static
    1、[靜態全域變數] //在全域變數前,加上關鍵字static,該變數就被定義成為一個靜態全域變數。

     靜態全域變數有以下特點:
        1)該變數在全域資料區分配記憶體;
        2)未經初始化的靜態全域變數會被程式自動初始化為0(自動變數的值是隨機的,除非它被顯式初始化);
        3)靜態全域變數在聲明它的整個檔案都是可見的,而在檔案之外(extern)是不可見的; 
  定義全域變數就可以實現變數在檔案中的共用,但定義靜態全域變數還有以下好處:
       1)靜態全域變數不能被其它檔案所用;
       2)其它檔案中可以定義相同名字的變數,不會發生衝突;

    2、[靜態局部變數] 在局部變數前,加上關鍵字static,該變數就被定義成為一個靜態局部變數。

    通常,在函數體內定義了一個變數,每當程式運行到該語句時都會給該局部變數分配棧記憶體。但隨著程式退出函數體,系統就會收回棧記憶體,局部變數也相應失效。但有時候我們需要在兩次調用之間對變數的值進行儲存。通常的想法是定義一個全域變數來實現。但這樣一來,變數已經不再屬於函數本身了,不再僅受函數的控制,給程式的維護帶來不便。
靜態局部變數正好可以解決這個問題。靜態局部變數儲存在全域資料區,而不是儲存在棧中,每次的值保持到下一次調用,直到下次賦新值。
    靜態局部變數有以下特點:
      1)該變數在全域資料區分配記憶體;
      2)靜態局部變數在程式執行到該對象的聲明處時被首次初始化,即以後的函數調用不再進行初始化;
      3)靜態局部變數一般在聲明處初始化,如果沒有顯式初始化,會被程式自動初始化為0;
      4)它始終駐留在全域資料區,直到程式運行結束。但其範圍為局部範圍,當定義它的函數或語句塊結束時,其作      用域隨之結束;

    3、靜態函數
    在函數的傳回型別前加上static關鍵字,函數即被定義為靜態函數。靜態函數與普通函數不同,它只能在聲明它的檔案當中可見,不能被其它檔案使用。
   定義靜態函數的好處:
      1)靜態函數不能被其它檔案所用;
      2)其它檔案中可以定義相同名字的函數,不會發生衝突;

二、物件導向的static關鍵字(類中的static關鍵字)
1、待用資料成員
    在類內資料成員的聲明前加上關鍵字static,該資料成員就是類內的待用資料成員。
   待用資料成員有以下特點:
      1)而待用資料成員被當作是類的成員。無論這個類的對象被定義了多少個,靜態數 據成員在程式中也只有一份拷貝,由該類型的所有對象共用訪問。
      2)待用資料成員儲存在全域資料區,屬於本類的所有對象共用,所以,它不屬於特定的類對象,在沒有產生類對象時其範圍就可見,即在沒有產生類的執行個體時,我們就可以操作它;
 同全域變數相比,使用待用資料成員有兩個優勢:
     1)待用資料成員沒有進入程式的全域名字空間,因此不存在與程式中其它全域名字衝突的可能性;
     2)可以實現[資訊隱藏]。待用資料成員可以是private成員,而全域變數不能;

2、靜態成員函數
    它為類的全部服務而不是為某一個類的具體物件服務。與普通函數相比,靜態成員函數由於不是與任何的 對象相聯絡,因此它不具有this指標。從這個意義上講,它無法訪問屬於類對象的非待用資料成員,也無法訪問非靜態成員函數,它只能調用其餘的靜態成員函數。
  關於靜態成員函數,可以總結為以下幾點:
    1)出現在類體外的函數定義不能指定關鍵字static;
    2)靜態成員之間可以相互訪問,包括靜態成員函數訪問待用資料成員和訪問靜態成員函數;
    3)非靜態成員函數可以任意地訪問靜態成員函數和待用資料成員;
    4)靜態成員函數不能訪問非靜態成員函數和非待用資料成員

-----------------------------------EXTERN----------------------------
EXTERN
1  基本解釋
    extern可以置於變數或者函數前,以標示變數或者函數的定義在別的檔案中,提示編譯器遇到此變數和函數時在其他模組中尋找其定義。通過這種行為它告訴編譯器:該變數/函數的定義已經存在在某個地方了,讓編譯器到其他的模組去尋找它的定義。
    另外,extern也可用來進行連結指定。

2. extern   “C”  
  使用extern“C”主要是因為C++語言在編譯的時候為了實現多態,會將函數名和函數結合起來形成另外一種函數名(總之就是說編譯後的函數名與你之前自己聲明時的函數名會不一樣),而C語言中無多態的概念當然也就不會有這種奇異的名字變化問題。這是問題就出現了,當你要在C++中調用C函數時,由於名字的不同,所以它會找不到所調用的這個函數的定義,因而會出錯。  
  為瞭解決這一C與C++的矛盾衝突,就有了extern "C'。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.