C/C++的const區別

一、const基礎知識(用法、含義、好處)html

int main()
{
    const int a;   //a爲const,常數型數
    int const b;  //b爲const,常數型數
    const int *c;  //c爲const,指向長整型數的指針(所指向的內存數據不能修改,但自己能夠修改)
    int *const d;  //int*爲const,常量指針(指針變量不能被修改,可是它所指向內存空間能夠被修改)
    const int * const e;  //int*爲const;e爲const,指向常整形的常指針(指針和它所指向的內存空間,都不能被修改)
    
    return 0;
}    

const在 * 左邊,變量爲const;c++

const在 * 右邊,指針爲const.數組

 

int func1(const)安全

初級理解:const是定義常量==》const意味着只讀函數

 

const好處this

//合理的利用constspa

一、指針作函數參數,能夠有效的提升代碼的可讀性,減小bug.指針

二、清楚的分清參數的輸入和輸出特性htm

 

int setTeacher_err(const Teacher *p);對象

const修改形參的時候,在利用形參不能修改指針所指向 的內存空間

 

二、C中的「冒牌貨」

//c語言中的const是一個冒牌貨,能夠被指針間接修改

//c++中const是一個真正的常量,不能被修改

int main()
{
  //好像a是一個常量,但其實不是
    const int a=10;
    int *p=(int *)&a;
    printf("a=%d\n",a);
    
    *p=11;//間接賦值,c語言會賦值成功,c++賦值不成功
    printf("a=%d\n",a);

    return 0;
} 

c的結果:

  a=10

  a=11

c++的結果:

  a=10

  a=10

解釋:

c++編譯器對const常量的處理:

當遇見常量聲明時,在符號表中放入常量 ==》 問題,如何解釋取地址?

  編譯過程當中若發現使用常量則直接以符號表中的值替換。

  編譯過程當中若發現對const使用了extern或者&操做符,則給對應的常量和分配存儲空間(兼容C)

聯想:下面的等式是否成立?

int &a = 1(err) & const int &a = 10

 

注意:c++編譯器雖然可能爲const常量分配空間但不會使用器存儲空間中的值。

 

結論:

 C語言中的const變量

  c語言中的const變量是隻讀變量,有本身的存儲空間。

C++中的const常量

  可能分配存儲空間,也可能不分配存儲空間

  當const常量爲全局,而且須要在其餘文件中使用,會分配存儲空間。

  當使用&操做符取const常量的地址時,會分配存儲空間。

  當const int &a=10;const 修飾引用時,也會分配存儲空間。

 

三、const在C和C++中的含義(筆試熱點):

 

⑴C中的const,功能比較單一,較容易理解:
做用:被修飾的內容不可更改。
使用場合:修飾變量,函數參數,返回值等。(c++中應用場合要豐富的多)
特色: 是運行時const,所以不能取代#define用於成爲數組長度等須要編譯時常量的狀況。同時由於是運行時const,能夠只定義而不初始化,而在運行時初始化。如 const int iConst;。 另外,在c中,const變量默認是外部連接,所以在不一樣的編譯單元中若是有同名const變量,會引起命名衝突,編譯時報錯。


⑵c++中的const:

a、非類成員const:

①const變量默認是內部鏈接的,所以在不一樣的編譯單元中能夠有同名的const 變量定義。

②編譯時常量,所以能夠像#define同樣使用,並且由於上面一點,能夠在頭文件中定義const變量,包含的不一樣的cpp文件(編譯單元)中使用而不引發命名衝突。

③編譯器默認不爲const變量分配內存,除非:1. 使用 extern 申明, 2:程序中有引用const 變量的地址。 

④c++中臨時對象/內置變量默認具備const屬性。

b、類中的const:

與c語言中的const同樣,只是運行時常量,不能做爲數組維數使用,即不能取代#define

 在類中使用下面兩種方式取代#define:

  1:static const... 

  2 : enum{....}//enum 不佔存儲空間。

類中的const 變量佔用存儲空間

③類中的const成員變量須要在構造函數初始化列表中初始化

④const 對象:在該對象生命週期內,必須保證沒有任何成員變量被改變const對象只能調用const成員函數

const成員函數: void fun() const ... 不只能被const對象調用,也能被非const對象調用,所以,若是確認一個任何成員函數不改變任何成員變量,應該習慣性將該函數定義成const類型。

⑥若是一個對象被定義成const,那麼該const對象「可能」會被放入到ROM當中,這在嵌入式開發當中有時很是重要。

 

 四、const和#define的區別

 const分配內存的時機,是編譯器編譯期間,與#define相同 

 C++中的const常量相似於宏定義#define

  const int c=5  等價於 #define c 5

1) 編譯器處理方式不一樣 define宏是在預處理階段展開。 const常量是編譯運行階段使用。

2) 類型和安全檢查不一樣 define宏沒有類型,不作任何類型檢查,僅僅是展開。 const常量有具體的類型,在編譯階段會執行類型檢查

注意:儘可能以const替換#define

 

五、類成員中的const變量

> 類中的const成員變量都要放在初始化列表之中進行
  > const數據成員
  > 引用數據成員
  > 對象數據成員(內置類)

  const成員函數
  > void print() const => const 類名 * const this
  > 在其內部是不能修改數據成員
  > 也不能調用非const成員函數
  > const對象只能調用const成員函數,必需要提供一個const版本的成員函數

再深刻探討類的const成員和成員函數,參考:https://www.cnblogs.com/cthon/p/9178701.html

補充:

> 類中的static數據成員須要在類以外進行初始化

  > 被類或類建立的對象共享
  > 全局/靜態區

  靜態成員函數
  > 它的形參列表之中沒有隱含的this指針
  > 不能調用非靜態的數據成員
  > 不能調用非靜態的成員函數
  > 只能調用靜態的成員
  > 能夠直接經過類名調用
再深刻探討類的static成員和成員函數,參考:https://www.cnblogs.com/cthon/p/9178527.html

相關文章
相關標籤/搜索