最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2017年07月18日 14:27:10   作者:滴巴戈  
簡單的說const關(guān)鍵字修飾的變量具有常屬性,也就是說它所修飾的變量不能被修改,下文給大家介紹C/C++中const關(guān)鍵字的用法及其與宏常量的比較,需要的朋友可以參考下

1.const關(guān)鍵字的性質(zhì)

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

2.修飾局部變量

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

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

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

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

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

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

3.修飾指針

常量指針是指針?biāo)赶虻膬?nèi)容是常量,不可被修改。

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

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

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;

它們的區(qū)別在于const的位置,可以這樣記憶:const在“*”前面時它修飾(*n),而*n是n所指向的變量,所以是常量指針,const在“*”后面時它修飾(n),使指針變?yōu)槌A?,所以是指針常量?/p>

指向常量的常指針

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

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

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

4.修飾引用

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

兩種定義形式在本質(zhì)上是一樣的

5.函數(shù)中使用const

(1)修飾函數(shù)參數(shù)

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

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

其中 strsrc是輸入?yún)?shù),strdes是輸出參數(shù)。給 strsrc 加上 const 修飾后,如果函數(shù)體內(nèi)的語句試圖改動 sresrc 的內(nèi)容,編譯器將指出錯誤。

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

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

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

另外當(dāng)參數(shù)為引用時

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

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

(2)修飾函數(shù)返回值

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

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

6.修飾類相關(guān)

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

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

(2)const修飾成員函數(shù)

用const修飾的類成員函數(shù),在該函數(shù)體內(nèi)不能改變該類對象的任何成員變量, 也不能調(diào)用類中任何非const成員函數(shù)。一般寫在函數(shù)的最后來修飾。

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

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

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

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

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

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

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)在類內(nèi)重載成員函數(shù)

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

另外,const數(shù)據(jù)成員只在某個對象生存期內(nèi)是常量,而對整個類而言是可變的,因為類可以創(chuàng)建多個對象,不同對象的const數(shù)據(jù)成員值可以不同。

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

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

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

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

7.修飾全局變量

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

8.const常量與宏常量的區(qū)別

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

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

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

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

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

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

(3)提高了效率 

 宏定義是一個“編譯時”概念,在預(yù)處理階段展開,不能對宏定義進(jìn)行調(diào)試,生命周期結(jié)束于編譯時期。const常量是一個“運(yùn)行時”概念,在程序運(yùn)行時使用,類似于一個只讀數(shù)據(jù)。

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

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

防止意外的修改,增強(qiáng)程序的健壯性。

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

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

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

(6)定義域不同

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

(7)做函數(shù)參數(shù)

   宏定義不能作為參數(shù)傳遞給函數(shù);const常量可以在函數(shù)的參數(shù)列表中出現(xiàn)。

9.const_cast

const_cast運(yùn)算符用來修改類型的const或volatile屬性。

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

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

 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關(guān)鍵字的用法及其與宏常量的比較,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • OpenCV實(shí)現(xiàn)簡易標(biāo)定板

    OpenCV實(shí)現(xiàn)簡易標(biāo)定板

    這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)簡易標(biāo)定板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • 如何用C語言畫一個“圣誕樹”

    如何用C語言畫一個“圣誕樹”

    這篇文章主要介紹了如何用C語言畫一個“圣誕樹”,感興趣的小伙伴們可以參考一下
    2015-12-12
  • 簡單掌握桶排序算法及C++版的代碼實(shí)現(xiàn)

    簡單掌握桶排序算法及C++版的代碼實(shí)現(xiàn)

    桶排序是將要排序的算法按桶分組排序之后再遍歷匯總的一種線性排序算法,下面就讓我們來通過小例子簡單掌握桶排序算法及C++版的代碼實(shí)現(xiàn)^^
    2016-07-07
  • C語言Tinyhttpd服務(wù)器源碼剖析

    C語言Tinyhttpd服務(wù)器源碼剖析

    這篇文章主要為大家介紹了C語言Tinyhttpd服務(wù)器源碼剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • DSP中浮點(diǎn)轉(zhuǎn)定點(diǎn)運(yùn)算--舉例及編程中的心得

    DSP中浮點(diǎn)轉(zhuǎn)定點(diǎn)運(yùn)算--舉例及編程中的心得

    本文主要講解DSP浮點(diǎn)轉(zhuǎn)定點(diǎn)運(yùn)算舉例及編程中的心得 ,具有參考價值,需要的朋友可以參考一下。
    2016-06-06
  • 詳解C++中的ANSI與Unicode和UTF8三種字符編碼基本原理與相互轉(zhuǎn)換

    詳解C++中的ANSI與Unicode和UTF8三種字符編碼基本原理與相互轉(zhuǎn)換

    在C++編程中,我們有時需要去處理字符串編碼的相關(guān)問題,常見的字符編碼有ANSI窄字節(jié)編碼、Unicode寬字節(jié)編碼及UTF8可變長編碼。很多人在處理字符串編碼問題時都會有疑惑,即便是有多年工作經(jīng)驗的朋友也可能搞不清楚。所以有必要講一下這三種字符編碼以及如何去使用它們
    2021-11-11
  • C語言分裝實(shí)現(xiàn)三子棋游戲詳解

    C語言分裝實(shí)現(xiàn)三子棋游戲詳解

    這篇文章主要為大家詳細(xì)介紹了C語言分裝實(shí)現(xiàn)三子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • 舉例分析private的作用(c/c++學(xué)習(xí))

    舉例分析private的作用(c/c++學(xué)習(xí))

    我知道我們可以用 public 中的值,把private中的數(shù)據(jù)給提出來,但是還是搞不懂private該怎么用,或者說在一個具體程序中,private有什么用
    2020-08-08
  • C語言創(chuàng)建線程thread_create()的方法

    C語言創(chuàng)建線程thread_create()的方法

    這篇文章主要介紹了C語言創(chuàng)建線程thread_create()的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • C語言實(shí)現(xiàn)九大排序算法的實(shí)例代碼

    C語言實(shí)現(xiàn)九大排序算法的實(shí)例代碼

    這篇文章主要給大家介紹了關(guān)于C語言實(shí)現(xiàn)九大排序算法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01

最新評論

航空| 林周县| 台北市| 海城市| 叙永县| 来凤县| 荣成市| 定兴县| 呈贡县| 白朗县| 昌宁县| 柏乡县| 玉溪市| 海原县| 虹口区| 榆林市| 万州区| 和林格尔县| 石景山区| 呼和浩特市| 依安县| 吴忠市| 和硕县| 堆龙德庆县| 安达市| 绥中县| 东安县| 大余县| 常州市| 勐海县| 诸城市| 寿宁县| 太白县| 平度市| 墨竹工卡县| 贞丰县| 和田县| 上林县| 板桥市| 壶关县| 宜丰县|