C/C++的const區別


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

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;

const在 * 右邊,指針為const.

 

int func1(const)

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

 

const好處

//合理的利用const

1、指針做函數參數,可以有效的提高代碼的可讀性,減少bug.

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

 

int setTeacher_err(const Teacher *p);

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

 

2、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 修飾引用時,也會分配存儲空間。

 

3、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當中,這在嵌入式開發當中有時非常重要。

 

 4、const和#define的區別

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

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

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

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

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

注意:盡量以const替換#define

 

5、類成員中的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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM