常量指標和指標常量
阿新 • • 發佈:2019-01-01
指向常量的指標和指標常量2007年10月17日 星期三 16:501. 指向常量的指標
char ch[5] = “lisi”;
我們先定義了一個字元陣列,它有五個元素,我們用一個常量的字串對它進行了賦值,要注意的是,這種賦值形式只能在陣列定義的同時進行,為什麼這裡我們定義的5個元素則不是4個元素的字元陣列呢?要注意,對於常量字串來說,會自動在末尾加上一個”/0”,所以在這個地方我們定義的是5而不是4。
我們假定0088::4400是字元陣列ch在記憶體中分配的首地址,接下來我們用
const char * pStr = ch;
定義了一個指向常量的指標變數。要注意在這裡,const在char前面,其實const在char的前面或者在char的後面都一樣,不過一般我們把它定義在char的前面。用const char *去定義一個指向常量的指標變數,然後我們用這個字元陣列給這個這個指向常量的指標變數賦值。我們知道陣列名代表了陣列的首地址,那麼上面的操作就相當於把ch這個字元陣列的首地址賦給了這個指標變數。那麼我們所定義的pStr是指向常量的指標變數,也就是說我們不可以用pStr去修改它在記憶體當中的這個資料的內容,但是對於pStr本身的值,也就是地址值這個是可以修改的。表示常量的指標表示它所指向的物件是常量。我們再看下面的程式碼。
*pStr = ‘w’; //錯誤
pStr = ‘hqlong’;//正確
第一句我們想利用*pStr去修改第一個位元組所指向的內容,即,我們把這個指標的常量的第一個位元組的內容設為’w’,那麼這是錯誤的,因為我們通過上面知道,這是一個指向常量的指標變數,也就是這個指標變數所指地址的內容不能被修改,我們知道,常量是不能被修改的,所以在這裡,這樣的賦值是錯誤的。
第二個表示式,我們是用一個字串對這個變數賦值,這個操作就相當於把這個字串的地址賦給了這個變數。pStr它的內容,也就是這個指標值,或者地址是可以修改的,所以這個操作是允許的,是正確的。
要注意,雖然我們不能通過pStr去修改它所指向的記憶體的內容,對於上面的字元陣列來說,我們仍然可以去利用字元陣列去改變記憶體當中的資料的內容,所以在注意這點的區別。
我們在申明的時候,就申明瞭pStr是指向常量的指標,那麼就保證要我們在編譯的時候,就不能通過pStr去修改它在記憶體中所指的內容。我們在申明一個函式的時候,用指標來傳參,我們通常是把這個行參申明瞭指向常量的指標型別,這樣當實參傳進來之後,行參的型別是指向常量的指標型別,所以我們不能夠利用行參去修改它所指向的內容,從而保證了資料的一致性。
2. 指標常量
同樣們也定義了字元陣列:
char ch[5] = “list”;
char * const pStr = ch;
注意第二行,和前面的定義指向常量的指標的區別,const的位置是在*和pStr之間,而指向常量的指標則是在char前面或者緊跟其後。同樣我們用字元陣列給這個指標賦值,即把這個字元陣列的首地址賦給了這個指標。大家要注意,指標常量必須是我們定義的同時對它進行賦值,也就是說,我們不能先定義,過後才對其進行賦值。然後對於前面的指向常量的指標,我們則可以先定義好了,在下一行再對它進行賦值。所以一定要注意這裡的區別。
指標常量它表示指標本身是常量,也就是說對這個指標值是不可以修改,但指標所指內容我們是可以修改的,這和指向常量的指標正好相反。
還是舉一下上面的兩個例子:
pStr = ‘hqlong’;//錯誤
*pStr = ‘w’; //正確
第一句程式碼,我們把一個字串賦給這個指標變數,也就是把這個字串的首地址賦給這個字元變數,由於指標常量的地址是不可以修改的,所以在這裡給其地址進行修改是錯誤的,在我們編譯裡,會出錯。
第二句程式碼是想修改pStr所指記憶體的第一個位元組的內容,我們想把它修為’w’,這個操作是正確的,我們知道,指標常量的地址不可以被修改,但地址所指的內容是可以被修改的。
所以在這裡,大家要注意指向常量的指標和指標常量的區別,指向常量的指標所在記憶體地址中的內容我們不可以修改,因為它所指內容是常量。但我們可以修改它的地址,即可以通過修改它的地址值來修改它的值。而指標常量則正好相反,這個指標是常量,指標也就是地址,所以地址是個常量,所以我們不能對其地址進行修改,但可以對該地址內的值進行修改,所以大家一樣要注意。
上面的是我一直以後比較迷惑的地方,現在基本上明白是怎麼回事,希望能通過這篇文章使不清楚指向常量的指標和指標常量的朋友能夠理解這兩者的區別。