指標常量與常量指標(const用法總結)

2021-07-05 14:09:49 字數 4194 閱讀 6767

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...