C語言常量指針與指針常量

常量指針,表述爲「是常量的指針」,就是指向常量的指針,關鍵字 const 出如今 * 左邊,表示指針所指向的地址的內容是不可修改的,但指針自身可變。ios

指針常量,表述爲 "是指針的常量", 指針吱聲是一個常量,關鍵字 const 出如今 * 右邊,表示指針自身不可變,但其所指向的地址的內容是能夠被修改的。函數

例:spa

                常量指針:const char* ptr = "hello"指針

                指針常量:char* const ptr = "hello"code

    這裏看關鍵字靠着誰近,const靠着ptr近說明就是指針常量,就是指針自身不能改變,但所指向的數據能夠變;const靠着類型近,說明指針所指向的內容不可變,但指針能夠變。內存

常量指針有兩種寫法:const既能夠寫在類型前,又能夠寫在類型後。如上面的例子,常量指針: char const* ptr = "hello" 也是正確的。字符串

最後在舉個例子,與迭代器常常在一塊兒用。若但願迭代器所指向的東西不可變,則須要的是 const_iterator。例:it

std::vector<int>::const_iterator iter = vec.begin();
*iter = 10; //錯誤,iter是常量指針
iter++;//正確,iter自己可變

若但願迭代器自己不可變,指向的內容可變,則能夠這樣寫:io

const std::vector<int>::iterator iter = vec.beign();
*iter = 10;//正確,指針常量
iter++;  //錯誤,指針自己不可變

指針常量定義時必須初始化,不然報編譯錯誤,由於此時不賦值便沒有機會賦值了。編譯

下面看幾個簡單的例子,能夠說明他們的區別:

第一個

#include <iostream>
using namespace std;
int main()
{
    char *str1 = {"hello"};
    char *str2 = {"hello world"};
    char * const ptr1 = str1;
    //指針常量--指針自己是常量,指向的地址
    //不能夠變化,可是指向的地址所對應的內容
    //能夠變化
    ptr1 = str2; //錯誤,由於這是一個指針常量
    //改變指向的地址了
    cout << *ptr1 << endl;
    return 0;
}
//編譯錯誤 error: assignment of read-only variable 'ptr1'

第二個

#include <iostream>
using namespace std;
int main()
{
    char *str1 = {"hello"};
    char *str2 = {"hello world"};
    char * const ptr1 = str1;
    //指針常量--指針自己是常量,指向的地址
    //不能夠變化,可是指向的地址所對應的內容
    //能夠變化
    ptr1 = "A";
    //錯誤,顯示內存錯誤,由於"hello"爲常量
    //不得修改,意指指針常量中,指針不得改
    //常量也不得改
    cout << *ptr1 << endl;
    return 0;
}

第三個

#include <iostream>
using namespace std;
int main()
{
    char *str1 = {"hello"};
    char *str2 = {"hello world"};
    const char *ptr1 = str1;
    //常量指針--指向字符串常量,所指向的字符串
    //內容不能變,可是指向的地址能夠變化
    //至關於在此處將前邊的str1追加定義爲常量
    ptr1 = str2;//正確 由於指向的地址是能夠變化的
    cout << ptr1;
    return 0;
}
//輸出 hello world
#include <iostream>
using namespace std;
int main()
{
    char *str1 = {"hello"};
    char *str2 = {"hello world"};
    const char *ptr1 = str2;
    //常量指針--指向字符串常量,所指向的字符串
    //內容不能變,可是指向的地址能夠變化
    //至關於在此處將前邊的str1追加定義爲常量
    ptr1 = 'A';//錯誤,由於指向的地址的內容是不能夠變化的
    cout << ptr1;
    return 0; 
}

相信從上面四個簡單的例子能夠看出他們不同的地方吧,在這裏要請你們注意一下的地方是:

指針常量的申明:const 放在*和指針名之間 Type* const   pointer;

常量指針的申明:const放在類型說明符以前 const Type*  pointer;

實際分兩部分: type* 爲指針 const 爲常量 自由組合便成爲指針常量,常量指針

常量指針、指針常量,個人判斷原則是 const 和 * 的前後順序。const在前常量指針,常量內容不可變,指針可變

*號在前,指針常量,指針不可變,內容可變

const 還能夠修飾函數:

若是給以「指針傳遞」方式的函數返回值加 const修飾,那麼函數返回值(即指針)的內容不能被修改,該返回值只能被賦給加const修飾的同類型指針。例如函數

const char * GetString(void);

以下語句將出現編譯錯誤:

char *str = GetString();

正確的用法是

const char *str = GetString();

若是函數返回值採用 「值傳遞方式」,因爲函數會把返回值複製到外部臨時的存儲單元中,加const修飾沒有任何價值。

相關文章
相關標籤/搜索