const是乙個c語言的關鍵字,它限定乙個變數不允許被改變。使用const在一定程度上可以提高程式的安全性和可靠性
指向常量的指標:
const int *pa;
int const *pa;
兩者等價。因為指向常量的指標有時候會指向常量,所以它具有這個性質:「不能靠解引用改變它指向的物件的值」,以此保護它所指向的常量的常量性:
*pa =d; // 不可行(d是已經宣告過的整型)
但指標本身的值是可變的:
pa=& d; // 可行(d是已經宣告過的整型)
而且指向常量的指標有時候也會指向變數,如下:
int t,u;
const int *pa;
pa =&t; //可行,指向變數t
pa =&u; //也可行,指向變數u
我們可以把它理解成:「為了指向常量而發明的指標」,這樣比較貼切。
常量指標:
int *const pa =&n; // n是之前已經宣告過的整型變數,注意必須是變數,理由見下
「常量指標」即指標本身的值是常量,但「能靠解引用改變它指向的物件的值」,如下:
pa=&d; // 不可行(d是已經宣告過的整型)
*pa =d; // 可行(d是已經宣告過的整型)
因為常量指標也是一種const常量,所以它同樣必須在第一次宣告時就初始化,不過它的初始值縮小為只能是變數(的位址),因為只有變數才能確保以後能靠解引用而改變它指向的物件的值。這使得常量指標不象一般的const常量,用變數或常量初始化都可以。
也就是說,常量指標反而總是指向變數的。
舉例:typedef char * pstr;
char string[4] = "abc";
const char *p1 = string;
const pstr p2 = string;
p1++;
p2++;
答案與分析:
問題出在p2++上。
1)、const使用的基本形式: const char m;
限定m不可變。
2)、替換1式中的m, const char *pm;
限定*pm不可變,當然pm是可變的,因此問題中p1++是對的。
3)、替換1式char,const newtype m;
限定m不可變,問題中的charptr就是一種新型別,因此問題中p2不可變,p2++是錯誤的。
char *p = "i'm hungry!";
p[0]= 'i';
答案與分析:
上面的**可能會造成記憶體的非法寫操作。分析如下, 「i'm hungry」實質上是字串常量,而常量往往被編譯器放在唯讀的記憶體區,不可寫。p初始指向這個唯讀的記憶體區,而p[0] = 'i'則企圖去寫這個地方,編譯器當然不會答應。
總結:
1)、const在前面
const int nvalue; //nvalue是const
const char *pcontent; //*pcontent是const, pcontent可變
const (char *) pcontent;//pcontent是const,*pcontent可變
char* const pcontent; //pcontent是const,*pcontent可變
const char* const pcontent; //pcontent和*pcontent都是const
2)、const在後面,與上面的宣告對等
int const nvalue; // nvalue是const
char const * pcontent;// *pcontent是const, pcontent可變
(char *) const pcontent;//pcontent是const,*pcontent可變
char* const pcontent;// pcontent是const,*pcontent可變
char const* const pcontent;// pcontent和*pcontent都是const
答案與分析:
const和指標一起使用是c語言中乙個很常見的困惑之處,在實際開發中,特別是在看別人**的時候,常常會因為這樣而不好判斷作者的意圖,下面講一下我的判斷原則:
沿著*號劃一條線,const和誰在一邊,那麼誰就是const,即const限定的元素就是它。你可以根據這個規則來看上面宣告的實際意義,相信定會一目了然。
另外,需要注意:
對於const (char *) ; 因為char *是乙個整體,相當於乙個型別(如 char),因此,這是限定指標是const。
const用法主要是防止定義的物件再次被修改,定義物件變數時要初始化變數
下面我就介紹一下幾種常見的用法
1.用於定義常量變數,這樣這個變數在後面就不可以再被修改
const int val = 10;
//val = 20; //錯誤,不可被修改
2. 保護傳參時引數不被修改,如果使用引用傳遞引數或按位址傳遞引數給乙個函式,在這個函式裡這個引數的值若被修改,
則函式外部傳進來的變數的值也發生改變,若想保護傳進來的變數不被修改,可以使用const保護
void fun1(const int &val)
void fun2(int &val)
void main()
如果只想把值傳給函式,而且這個不能被修改,則可以使用const保護變數,有人會問為什麼不按值傳遞,按值傳遞還需要把這個值複製一遍,
而引用不需要,使用引用是為了提高效率//如果按值傳遞的話,沒必要加const,那樣根本沒意義
3. 節約記憶體空間,
#define pi 3.14 //使用#define巨集
const double pi = 3.14 //使用const,這時候pi並沒有放入記憶體中
double a = pi; //這時候才為pi分配記憶體,不過後面再有這樣的定義也不會再分配記憶體
double b = pi; //編譯時分配記憶體
double c = pi; //不會再分配記憶體,
double d = pi; //編譯時再分配記憶體
const定義的變數,系統只為它分配一次記憶體,而使用#define定義的常量巨集,能分配好多次,這樣const就很節約空間
4.類中使用const修飾函式防止修改非static類成員變數
class
private:
int a ;
static int b;
}5.修飾指標
const int *a; 或 int const *a; //const修飾指向的物件,a可變,a指向的物件不可變
int *const a; //const修飾指標a, a不可變,a指向的物件可變
const int *const a; //指標a和a指向的物件都不可變
6.修飾函式返回值,防止返回值被改變
const int fun();
接收返回值的變數也必須加const
const int a = fun(); //接收的變數也要是const的,int a = fun()是錯誤的
7.修飾類的成員變數
使用const修飾的變數必須初始化,在類中又不能在定義時初始化,
如;class
初始化const int型別(沒有static),在類的建構函式上初始化
class test
private:
const int b ;
}初始化staticconst int這個型別的(帶有static的),在類的外面初始化
class test
const int test::c=10; //類的外部初始化c為10
8.const定義的物件變數只能作用於這個程式該c/c++檔案,不能被該程式的其他c/c++檔案呼叫,
如file1.cpp中 const int val;
在file2.cpp中, extern intval; //錯誤,無法呼叫,
要想const定義的物件變數能被其他檔案呼叫,定義時必須使用extern修飾為
extern const int val;
非const變數預設為extern,要是const能被其他檔案訪問必須顯示指定為extern
常量指標與指標常量(const用法)
初了解,const是在c語言中為了提高程式的安全性和可靠性而用來修飾資料型別的,const修飾的資料型別是指常型別,常型別的變數或物件的值是不能被更新的,即相當於限定為 唯讀 的狀態。即指向常量的指標,該指標所指向的是乙個常量,常量的值不能通過解引用來改變,但是這個指標的指向可以改變 如 const...
指標常量與常量指標(const用法總結)
const是乙個c語言的關鍵字,它限定乙個變數不允許被改變。使用const在一定程度上可以提高程式的安全性和可靠性 指向常量的指標 const int pa int const pa 兩者等價。因為指向常量的指標有時候會指向常量,所以它具有這個性質 不能靠解引用改變它指向的物件的值 以此保護它所指向...
const常量 指向常量的指標和常量指標
1 先看const常量的情況 const int a 2 int const b c c是已經宣告過的整型 兩者都可以。本地的const常量必須在第一次宣告時就初始化,用變數或常量初始化都可以,只是初始化一次以後它的值就不能再改變了,此所謂const的含義。2 接著看指向常量的指標 const in...