亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

詳解C/C++中const關鍵字的用法及其與宏常量的比較

2020-01-26 14:00:52
字體:
來源:轉載
供稿:網友

1.const關鍵字的性質

簡單來說:const關鍵字修飾的變量具有常屬性。 即它所修飾的變量不能被修改。

2.修飾局部變量

 const int a = 10; int const b = 20;

這兩種寫法是等價的,都是表示變量的值不能被改變,需要注意的是,用const修飾變量時,一定要給變量初始化,否則之后就不能再進行賦值了,而且編譯器也不允許不賦初值的寫法:

在C++中不賦初值的表達一寫出來,編譯器即報錯,且編譯不通過。

在C中不賦初值的表達寫出來時不報錯,編譯時只有警告,編譯可以通過。而當你真正給它賦值時才會報錯,那么沒有初值也不能被賦值這樣的變量有什么用哪?

 const chsr* p = "qwerty"; //const用于修飾常量靜態字符串

如果沒有const的修飾,我們可能會在后面有意無意的寫p[4]='x'這樣的語句,這樣會導致對只讀內存區域的賦值,然后程序會立刻異常終止。有了const,這個錯誤就能在程序被編譯的時候就立即檢查出來,這就是const的好處。讓邏輯錯誤在編譯期被發現。(這個特性在C/C++中相同)

3.修飾指針

常量指針是指針所指向的內容是常量,不可被修改。

 const int * n?。健。Γ? int const * n?。健。Γ?

上面兩種寫法也是等價的,性質如下:

1)常量指針通過不能這個指針改變變量的值,但是可以通過其他的引用來改變變量的值的。

const int *n = &a;  *n = b;

上面的寫法報錯

 int c = 3; const int *n = &a; a = 10; a = c;

這樣賦值是可以的。

2)常量指針指向的值不能改變,但是指針本身可以改變,即常量指針可以指向其他的地址。

  int a = 1; int b = 2; const int *n = &a; n = &b;

指針常量是指指針本身是個常量,不能在指向其他的地址,寫法如下: 

 int a = 1;  int b = 2;  int * const n = &a;  *n = b;  b = a;

而這么寫是錯誤的

int a = 1; int b = 2; int c = 3; int * const n = &a; n = &b;

它們的區別在于const的位置,可以這樣記憶:const在“*”前面時它修飾(*n),而*n是n所指向的變量,所以是常量指針,const在“*”后面時它修飾(n),使指針變為常量,所以是指針常量。

指向常量的常指針

 const int * const p= &a; int const * const p= &a;

指針指向的位置不能改變并且也不能通過這個指針改變變量的值,但是依然可以通過變量賦值,或其他的普通指針改變變量的值。

(這種用法在C和C++中是相同的。)

4.修飾引用

int a = 1; int const &a = b; const int &a = b;

兩種定義形式在本質上是一樣的

5.函數中使用const

(1)修飾函數參數

根據const修飾指針的特性,const修飾函數的參數也是分為三種情況

 void StrCopy(char *strdes, const char *strsrc);//防止修改指針指向的內容

其中 strsrc是輸入參數,strdes是輸出參數。給 strsrc 加上 const 修飾后,如果函數體內的語句試圖改動 sresrc 的內容,編譯器將指出錯誤。

 void swap ( int * const p1 , int * const p2 ) //防止修改指針指向的地址

指針p1和指針p2指向的地址都不能修改。

void test ( const int * const p1 , const int * const p2 ) //以上兩種的結合

另外當參數為引用時

void function(const Class& Var); //引用參數在函數內不可以改變  void function(const TYPE& Var); //引用參數在函數內為常量不可變

(這樣的一個const引用傳遞和最普通的函數按值傳遞的效果是一模一樣的,他禁止對引用的對象的一切修改,唯一不同的是按值傳遞會先建立一個類對象的副本, 然后傳遞過去,而它直接傳遞地址,所以這種傳遞比按值傳遞更有效.另外只有引用的const傳遞可以傳遞一個臨時對象,因為臨時對象都是const屬性, 且是不可見的,他短時間存在一個局部域中,所以不能使用指針,只有引用的const傳遞能夠捕捉到這個家伙。)

(2)修飾函數返回值

如果給以“指針傳遞”方式的函數返回值加 const 修飾,那么函數返回值(即指針)的內容不能被修改,該返回值只能被賦給加const 修飾的同類型指針。

const int * fun2() //調用時 const int *pValue = fun2();        //我們可以把fun2()看作成一個變量,即指針內容不可變。  c.int* const fun3() //調用時 int * const pValue = fun2();        //我們可以把fun2()看作成一個變量,即指針本身不可變。 const int fun1() //這個其實無意義,因為參數返回本身就是賦值。

6.修飾類相關

(1)用const修飾的類成員變量,只能在類的構造函數初始化列表中賦值,不能在類構造函數體內賦值。

class A{public: A(int x) : a(x) // 正確 {   //a = x; // 錯誤 }private: const int a;};

(2)const修飾成員函數

用const修飾的類成員函數,在該函數體內不能改變該類對象的任何成員變量, 也不能調用類中任何非const成員函數。一般寫在函數的最后來修飾。

class A{public: int& getValue() const {  // a = 10; // 錯誤  return a; }private: int a;   // 非const成員變量};

a. const成員函數不被允許修改它所在對象的任何一個數據成員。

b. const成員函數能夠訪問對象的const成員,而其他成員函數不可以。

(3)const修飾類對象/對象指針/對象引用

用const修飾的類對象表示該對象為常量對象,該對象內的任何成員變量都不能被修改。對于對象指針和對象引用也是一樣。

因此不能調用該對象的任何非const成員函數,因為對非const成員函數的調用會有修改成員變量的企圖。

class A{ public: void funcA() {} void funcB() const {}};int main{ const A a; a.funcB(); // 正確 a.funcA(); // X const A* b = new A(); b->funcB(); // 正確 b->funcA(); // X}

(4)在類內重載成員函數

class A { public:  void func() {}  void func() const {} // 重載 };

另外,const數據成員只在某個對象生存期內是常量,而對整個類而言是可變的,因為類可以創建多個對象,不同對象的const數據成員值可以不同。

class A{public: A(int size)    : _size(size) // 正確 {}private: const int _size;};A a(10); //對象a的_size值為10A b(20); //對象b的_size值為20

那么,怎樣才能建立在整個類中都恒定的常量呢?用枚舉常量。

class A{public: enum{SIZE1 = 10, SIZE2 = 20};//枚舉常量private:  int arr1[SIZE1];  int arr2[SIZE2];};

枚舉常量不會占用對象的存儲空間,它們在編譯時被全部求值。但缺點是隱含數據類型是只能整數,最大值有限,且不能表示浮點數。

7.修飾全局變量

全局變量的作用域是整個文件,我們應該盡量避免使用全局變量,以為一旦有一個函數改變了全局變量的值,它也會影響到其他引用這個變量的函數,導致除了bug后很難發現,如果一定要用全局變量,我們應該盡量的使用const修飾符進行修飾,這樣方式不必要的以為修改,使用的方法與局部變量是相同的。

8.const常量與宏常量的區別

(1).便于進行類型檢查

const常量有數據類型,而宏常量沒有數據類型。編譯器可以對前者進行類型安全檢查,而對后者只進行字符替換,沒有類型安全檢查,并且在字符替換時可能會產生意料不到的錯誤(邊際效應)。

//例子: void f(const int i) { .........} //對傳入的參數進行類型檢查,不匹配進行提示

(2)可以節省空間,避免不必要的內存分配

const定義常量從匯編的角度來看,只是給出了對應的內存地址,而不是象#define一樣給出的是立即數,所以,const定義的常量在程序運行過程中只有一份拷貝,而#define定義的常量在內存中有若干個拷貝。

#define PI 3.14159   //常量宏const doulbe Pi=3.14159; //此時并未將Pi放入ROM中    ...... double i=Pi; //此時為Pi分配內存,以后不再分配! double I=PI; //編譯期間進行宏替換,分配內存 double j=Pi; //沒有內存分配 double J=PI; //再進行宏替換,又一次分配內存!

(3)提高了效率 

 宏定義是一個“編譯時”概念,在預處理階段展開,不能對宏定義進行調試,生命周期結束于編譯時期。const常量是一個“運行時”概念,在程序運行時使用,類似于一個只讀數據。

編譯器通常不為普通const常量分配存儲空間,而是將它們保存在符號表中,這使得它成為一個編譯期間的常量,沒有了存儲與讀內存的操作,使得它的效率也很高

(4)可以保護被它修飾的東西

防止意外的修改,增強程序的健壯性。

void f(const int i) { i=10;//error! } //如果在函數體內修改了i,編譯器就會報錯 

(5)為函數重載提供了一個參考

 class A {   ...... void f(int i)  {......} //一個函數 void f(int i) const {......} //上一個函數的重載   ...... };

(6)定義域不同

 void f1 () {  #define N 12  const int n 12; } void f2 () {  cout<<N <<endl; //正確,N已經定義過,不受定義域限制  cout<<n <<endl; //錯誤,n定義域只在f1函數中。若想在f2中使用需定義為全局的 }

(7)做函數參數

   宏定義不能作為參數傳遞給函數;const常量可以在函數的參數列表中出現。

9.const_cast

const_cast運算符用來修改類型的const或volatile屬性。

(1)常量指針被轉化成非常量的指針,并且仍然指向原來的對象;

(2)常量引用被轉換成非常量的引用,并且仍然指向原來的對象。

 void func() {  const int a = 10;  int* p = const_cast<int*> (&a);  *p = 20;  std::cout<<*p; // 20  std::cout<<a;  // 10 }

注:C++中使用const 常量而不使用宏常量,即const 常量完全取代宏常量。

以上所述是小編給大家介紹的C/C++中const關鍵字的用法及其與宏常量的比較,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
乱亲女秽乱长久久久| 亚洲摸下面视频| 国产美女扒开尿口久久久| 中文字幕精品一区久久久久| 国内精久久久久久久久久人| 欧美国产日韩一区二区在线观看| 日韩电影免费在线观看| 日韩成人网免费视频| 欧美视频中文在线看| 91视频8mav| 中文字幕亚洲一区二区三区五十路| 91成人天堂久久成人| 国产精品亚洲第一区| 日日狠狠久久偷偷四色综合免费| 欧美亚洲日本黄色| 久久久噜噜噜久久久| 日韩精品在线视频观看| 久久久久久久久久久亚洲| 日韩欧美亚洲范冰冰与中字| 正在播放亚洲1区| 欧美怡红院视频一区二区三区| 国产精品久久久久久久av大片| 精品久久久久久| 久久久999国产精品| 热re99久久精品国产66热| 国产91精品视频在线观看| 日韩激情片免费| 色香阁99久久精品久久久| 久久久成人av| 高跟丝袜欧美一区| 91精品综合久久久久久五月天| 亚洲精品综合久久中文字幕| 欧美激情一区二区三区在线视频观看| 亚洲精品美女久久久久| 精品亚洲夜色av98在线观看| 亚洲一区二区三区在线视频| 一色桃子一区二区| 91日本在线视频| 亚洲欧美国产精品专区久久| 久久99精品久久久久久琪琪| 国产经典一区二区| 91av视频在线观看| 国产99久久精品一区二区 夜夜躁日日躁| 国产日韩欧美中文| 国产精品久久久av| 国产精自产拍久久久久久蜜| 尤物99国产成人精品视频| 亚洲国产精品国自产拍av秋霞| 最近中文字幕mv在线一区二区三区四区| 日韩视频免费大全中文字幕| 91色视频在线导航| 亚洲午夜激情免费视频| 欧美一级淫片aaaaaaa视频| 日韩二区三区在线| 亚洲小视频在线观看| 国产日韩欧美在线观看| 亚洲最大成人在线| 欧美性xxxx极品高清hd直播| 国产精品亚洲精品| 91免费的视频在线播放| 欧美性一区二区三区| 日韩av最新在线观看| 久久精品中文字幕电影| 欧美激情国产日韩精品一区18| 亚洲欧美制服丝袜| 人人爽久久涩噜噜噜网站| 国产视频在线观看一区二区| 亚洲图片在区色| 美女久久久久久久| 欧美老女人在线视频| 国产丝袜精品第一页| 亚洲人精选亚洲人成在线| 欧美在线视频免费| 91av视频在线观看| 成人黄色中文字幕| 麻豆乱码国产一区二区三区| 国产v综合ⅴ日韩v欧美大片| 夜色77av精品影院| 中文字幕在线看视频国产欧美| 亚洲激情自拍图| 97国产精品久久| 久久久国产成人精品| 成人国产精品免费视频| 精品福利樱桃av导航| 久久伊人精品视频| 26uuu日韩精品一区二区| 久久国产天堂福利天堂| 国产免费久久av| 精品久久久久久亚洲精品| 日本不卡视频在线播放| 91精品久久久久久久久久久久久| 亚洲高清福利视频| 亚洲精品久久视频| 最近2019年好看中文字幕视频| 国产精品免费一区二区三区都可以| 综合国产在线观看| 久久成人在线视频| 国语自产偷拍精品视频偷| 亚洲电影在线看| 欧美激情18p| 动漫精品一区二区| 日本精品久久中文字幕佐佐木| 伊人伊人伊人久久| 精品偷拍一区二区三区在线看| 日韩精品视频在线播放| 日韩欧美福利视频| 深夜福利日韩在线看| 2019av中文字幕| 国内精品久久久久久久| 精品国内自产拍在线观看| 在线色欧美三级视频| 欧美激情精品久久久久久黑人| 欧美老肥婆性猛交视频| 成人a级免费视频| 日本久久亚洲电影| 日韩av在线免播放器| 欧美大片大片在线播放| 日韩av一区二区在线| 2019中文在线观看| 日韩中文在线中文网在线观看| 精品中文字幕在线| 亚洲精品自拍第一页| 亚洲欧美日本伦理| 亚洲国产精品小视频| 国产精品电影网| 国产精品第一第二| 91产国在线观看动作片喷水| 色噜噜亚洲精品中文字幕| 91精品综合视频| www.午夜精品| 精品美女久久久久久免费| 欧美午夜精品久久久久久浪潮| 91天堂在线观看| 久久777国产线看观看精品| 亚洲女人初尝黑人巨大| 久久成年人免费电影| 欧美大片免费观看在线观看网站推荐| 成人激情视频在线观看| 久久久久亚洲精品国产| 国产区精品在线观看| 国产亚洲精品日韩| 亚洲国产精品推荐| 国产精品毛片a∨一区二区三区|国| 欧美猛交免费看| 国产中文字幕91| 国产精品电影一区| 最好看的2019年中文视频| 国产丝袜一区视频在线观看| 一区二区三区回区在观看免费视频| 久久精品国产96久久久香蕉| 久久精品99久久久久久久久| 色婷婷综合久久久久| 亚洲全黄一级网站| 色综合天天狠天天透天天伊人| 欧美亚洲激情视频| 亚洲第一天堂无码专区| 97免费视频在线播放| 欧美精品制服第一页| 欧美精品在线极品| 亚洲欧美色图片| 亚洲小视频在线观看| 国产精品va在线播放我和闺蜜| 尤物yw午夜国产精品视频| 日韩成人黄色av|