關於C/C++中的幾個關鍵字(C基礎)

轉載的別人的嘿嘿,基礎的基礎,基礎的東西老是最有用的東西
轉自:[url]http://www.cppblog.com/cc/archive/2007/09/11/32033.html[/url]
1)auto
  這個這個關鍵字用於聲明變量的生存期爲自動,即將不在任何類、結構、枚舉、聯合和函數中定義的變量視爲全局變量,而在函數中定義的變量視爲局部變量。這個關鍵字不怎麼多寫,由於全部的變量默認就是auto的。

(2)register

  這個關鍵字命令編譯器儘量的將變量存在CPU內部寄存器中而不是經過內存尋址訪問以提升效率。

(3)static

  常見的兩種用途:
    1>統計函數被調用的次數;
    2>減小局部數組創建和賦值的開銷.變量的創建和賦值是須要必定的處理器開銷的,特別是數組等含有較多元素的存儲類型。在一些含有較多的變量而且被常常調用的函數中,能夠將一些數組聲明爲static類型,以減小創建或者初始化這些變量的開銷.
  詳細說明:
    1>、變量會被放在程序的全局存儲區中,這樣能夠在下一次調用的時候還能夠保持原來的賦值。這一點是它與堆棧變量和堆變量的區別。
    2>、變量用static告知編譯器,本身僅僅在變量的做用範圍內可見。這一點是它與全局變量的區別。
    3>當static用來修飾全局變量時,它就改變了全局變量的做用域,使其不能被別的程序extern,限制在了當前文件裏,可是沒有改變其存放位置,仍是在全局靜態儲存區。
  使用注意:
    1>若全局變量僅在單個C文件中訪問,則能夠將這個變量修改成靜態全局變量,以下降模塊間的耦合度;
    2>若全局變量僅由單個函數訪問,則能夠將這個變量改成該函數的靜態局部變量,以下降模塊間的耦合度;
    3>設計和使用訪問動態全局變量、靜態全局變量、靜態局部變量的函數時,須要考慮重入問題(只要輸入數據相同就應產生相同的輸出)。

(4)const

  被const修飾的東西都受到強制保護,能夠預防意外的變更,能提升程序的健壯性。它能夠修飾函數的參數、返回值,甚至函數的定義體。
  做用:
    1>修飾輸入參數
      a.對於非內部數據類型的輸入參數,應該將「值傳遞」的方式改成「const引用傳遞」,目的是提升效率。例如將void Func(A a) 改成void Func(const A &a)。
      b.對於內部數據類型的輸入參數,不要將「值傳遞」的方式改成「const引用傳遞」。不然既達不到提升效率的目的,又下降了函數的可理解性。例如void Func(int x) 不該該改成void Func(const int &x)。
    2>用const修飾函數的返回值
      a.若是給以「指針傳遞」方式的函數返回值加const修飾,那麼函數返回值(即指針)的內容不能被修改,該返回值只能被賦給加const修飾的同類型指針。
       如對於: const char * GetString(void);
       以下語句將出現編譯錯誤:
        char *str = GetString();//cannot convert from 'const char *' to 'char *';
       正確的用法是:
       const char *str = GetString();
      b.若是函數返回值採用「值傳遞方式」,因爲函數會把返回值複製到外部臨時的存儲單元中,加const修飾沒有任何價值。 如不要把函數int GetInt(void) 寫成const int GetInt(void)。
    3>const成員函數的聲明中,const關鍵字只能放在函數聲明的尾部,表示該類成員不修改對象.
   說明:
    const type m; //修飾m爲不可改變
   示例:
    typedef char * pStr; //新的類型pStr;
    char string[4] = "abc";
    const char *p1 = string;
    p1++; //正確,上邊修飾的是*p1,p1可變
    const pStr p2 = string;
    p2++; //錯誤,上邊修飾的是p2,p2不可變,*p2可變
   同理,const修飾指針時用此原則判斷就不會混淆了。
    const int *value; //*value不可變,value可變
    int* const value; //value不可變,*value可變
    const (int *) value; //(int *)是一種type,value不可變,*value可變
              //邏輯上這樣理解,編譯不能經過,須要tydef int* NewType;
    const int* const value;//*value,value都不可變

(5)volatile

  代表某個變量的值可能在外部被改變,優化器在用到這個變量時必須每次都當心地從新讀取這個變量的值,而不是使用保存在寄存器裏的備份。它能夠適用於基礎類型如:int,char,long......也適用於C的結構和C++的類。當對結構或者類對象使用volatile修飾的時候,結構或者類的全部成員都會被視爲volatile.
  該關鍵字在多線程環境下常用,由於在編寫多線程的程序時,同一個變量可能被多個線程修改,而程序經過該變量同步各個線程。
  簡單示例:
   DWORD __stdcall threadFunc(LPVOID signal)
   {
     int* intSignal=reinterpret_cast(signal);
     *intSignal=2;
     while(*intSignal!=1)
     sleep(1000);
     return 0;
   }
  該線程啓動時將intSignal 置爲2,而後循環等待直到intSignal 爲1 時退出。顯然intSignal的值必須在外部被改變,不然該線程不會退出。可是實際運行的時候該線程卻不會退出,即便在外部將它的值改成1,看一下對應的僞彙編代碼就明白了:
     mov ax,signal
     label:
     if(ax!=1)
     goto label
  對於C編譯器來講,它並不知道這個值會被其餘線程修改。天然就把它cache在寄存器裏面。C 編譯器是沒有線程概念的,這時候就須要用到volatile。volatile 的本意是指:這個值可能會在當前線程外部被改變。也就是說,咱們要在threadFunc中的intSignal前面加上volatile關鍵字,這時候,編譯器知道該變量的值會在外部改變,所以每次訪問該變量時會從新讀取,所做的循環變爲以下面僞碼所示:
     label:
     mov ax,signal
     if(ax!=1)
     goto label
  注意:一個參數既能夠是const同時是volatile,是volatile由於它可能被意想不到地改變。它是const由於程序不該該試圖去修改它。

(6)extern

  extern 意爲「外來的」···它的做用在於告訴編譯器:有這個變量,它可能不存在當前的文件中,但它確定要存在於工程中的某一個源文件中或者一個Dll的輸出中。
相關文章
相關標籤/搜索