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
