const關鍵字總結

在C語言中

const是C語言中總結
1.修飾的變量,使其具備常屬性,使變量的值不能直接被改變。可是能夠經過指針來間接的修改變量的值。
2.便於進行類型檢查(在編譯時進行類型檢查),使編譯對處理內容有更多的瞭解,保護被修飾的東西,防止被意外修改,加強程序的健壯性。
3.方便的進行參數的調整和修改(相似於宏定義)
做用1說明:
修飾的變量,使其具備常屬性,使變量的值不能直接被改變。可是能夠經過指針來間接的修改變量的值
例如:ios

const int t=10;
//在之後的代碼中,程序不可直接對i進行修改
//可是可經過指針來間接的修改i變量中存的值

t=2;   //會報錯

int *p=(int *)&t;
*p=2;   //在此處就將i中的值存成2了

const修飾指針變量:c++

int main()
{
    int a = 10;
    const int *p = &a;     //const修飾int *,即p的指向,於是p指向的內容即經過pa解引用後不能被修改,可是p中存的內容能夠改變,即p的指向能夠改變
    int  * const q=&a;       //const修飾*,即q變量,於是q裏存的內容不能變,即q的指向不能改變,可是q指向的內容即a中的內容能夠修改。
    p++;//正確
    (*p)++;//錯誤
    q++;//錯誤
    (*q)++;//正確
    return 0;
}

因此看const修飾誰,要看const右面有什麼
好比:
int **const* p; 則經過*p來修改對應的內容則報錯安全

int **const** p; 則經過**p來修改內容則會報錯ide

經過const的特性,const能夠在不少地方派上用場
好比在傳參時,不想經過函數來改變實參值,在傳實參地址時,形參接收在前可加const修飾,這樣就不會在函數裏經過解引用來修改實參值了函數

  • 在C語言中,const不用來修飾函數,緣由看C++的用法

在C++中

在c++中:
1.const修飾變量的用法和做用與c語言同樣,可是有一點不一樣性能

#include <iostream>  
 using namespace std;  

 int main()  
  {  
     const int a = 1;  
     int* p = (int *)(&a);  
     *p = 2;  
     cout << "value of p: " << *p << endl;  
     cout << "value of a: " << a << endl;  
     cout << "address of p: " << p << endl;  
     cout << "address of a: " << &a << endl;    
     return 0;  
 } 
 輸出
 /*value of p: 2
value of a: 1
address of p: 0x7fbffff7fc
address of a: 0x7fbffff7fc

由答案可知,a並無像c語言中同樣,被p修改成2,這是爲何呢?
緣由: const int a實際上是保存在符號表中,無內存地址,但本身對a進行&a,那麼編譯器會爲a分配一個地址,但取a的值依然是從符號表中取值,而用指針int *p=&a;
*p=4這個值是改變a的內存所表示值,不會改變符號表中a的值。this

#include <iostream>  
  using namespace std;  
  const int a = 3;       //此時a是全局變量
  int main()  
  {  
      //const int a = 3;     
     int* p = const_cast<int*>(&a);  
     *p = 4;  
     cout << "value of p: " << *p << endl;  
     cout << "value of a: " << a << endl;  
     cout << "address of p: " << p << endl;  
     cout << "address of a: " << &a << endl;  

     return 0;  
 }

輸出結果
const關鍵字總結
會發生如此運行時錯誤
因而可知,在c++中全局const變量和局部const變量的編譯器處理的方法是不同的。由於全局const變量是不分配內存地址的,它編譯器放置在符號表中做爲編譯期常量,全局const變量放在只讀數據段中,受到只讀數據段的權限保護,當你修改一個只讀數據段中的內容時,會獲得一個運行時錯誤。而局部const變量是放在堆棧之中,由於在內存中有地址,經過修改地址中的值能夠達到修改const所指內存中值的目的。spa

2.此外,在c++中,const還可用來修飾成員函數,其用法是放在形參列表以後,
用來修飾隱式傳入構造函數中的this指針,代表在函數調用的過程當中,不可對this指向的內容進行修改,即不可修改調用這個構造函數對象中的內容。
被const修飾的成員函數,稱做爲const類型的成員函數
例如:指針

class Date
{
public:
    Date(int year = 1900, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
        cout << "Date(int,int,int):" << this << endl;
    }

    // 在const成員函數中,不能修改類的任何成員變量
    void PrintDate()const
    {
        //_year++;
        //即this->_year++;      會報錯
        // 在函數被修飾後,this的類型爲 const Date* const     (由於this指針原本就是const型的this不可修改指向,後面的const代表this指向裏的內容也不可修改) 
        _day++;    //√
        cout << _year << "-" << _month << "-" << _day << endl;
    }

private:
    int _year;
    int _month;
    mutable int _day;    //在成員變量名前加mutable關鍵字後,成員函數即便加const也可修改_day的值
};

int main()
{
Date d1;
d1. PrintDate();
}

用const修飾成員函數有如下注意事項:
1>const不可修飾其餘類外函數(對有this的函數纔有用)。不可調用構造函數,由於構造函數目的就是要修改爲員變量。
2>const對象不能夠調用非const成員函數。由於普通成員函數是能夠修改爲員變量的,若是容許修改,拿不可修改的const對象就會被修改了,不安全。
3>非const對象能夠調用const成員函數。由於普通變量可讀可寫,const函數只容許對調用對象進行讀,所以沒有什麼不可。
4>const成員函數不能夠調用非const成員函數。普通函數可對對象進行修改,在調用普通函數時可能會修改對象,所以const成員函數不能調用非const成員函數。
5>非const成員函數能夠調用const成員函數調試

const 變量與 define 宏定義的區別:

(1) 編譯器處理方式不一樣
define宏是在預處理階段展開。
const常量是編譯運行階段使用。
(2) 類型和安全檢查不一樣
define宏沒有類型,不作任何類型檢查,僅僅是展開。
const常量有具體的類型,在編譯階段會執行類型檢查。
(3) 存儲方式不一樣
define宏僅僅是展開,有多少地方使用,就展開多少次,不會分配內存。
const常量會在內存中分配(能夠是堆中也能夠是棧中)
const修飾能夠節省空間,避免沒必要要的內存分配(與宏定義的本質區別)

宏的優勢:1.加強代碼的複用性。2.提升性能。缺點:1.不方便調試宏。(由於預編譯階段進行了替換) 2.致使代碼可讀性差,可維護性差,容易誤用。 3.沒有類型安全的檢查

相關文章
相關標籤/搜索