若是還不是很理解,水木上也有高人對此進行解釋:數組
這裏的char ch[]="abc";
表示ch 是一個足以存放字符串初值和空字符'/0'的一維數組,能夠更改數組中的字符,可是char自己是不可改變的常量。
char *pch = "abc";
那麼pch 是一個指針,其初值指向一個字符串常量,以後它能夠指向其餘位置,但若是試圖修改字符串的內容,結果將不肯定。
______ ______ ______
ch: |abc\0 | pch: | ◎-----> |abc\0 |
______ ______ ______
char chArray[100];
chArray[i] 等價於 *(chArray+i)
和指針的不一樣在於 chArray不是變量 沒法對之賦值
另 事實上 i[chArray] 也等價於 *(chArray+i)
所以,總結以下:函數
1. char[] p表示p是一個數組指針,至關於const pointer,不容許對該指針進行修改。但該指針所指向的數組內容,是分配在棧上面的,是能夠修改的。優化
2. char * pp表示pp是一個可變指針,容許對其進行修改,便可以指向其餘地方,如pp = p也是能夠的。對於*pp = "abc";這樣的狀況,因爲編譯器優化,通常都會將abc存放在常量區域內,而後pp指針是局部變量,存放在棧中,所以,在函數返回中,容許返回該地址(實際上指向一個常量地址,字符串常量區);而,char[] p是局部變量,當函數結束,存在棧中的數組內容均被銷燬,所以返回p地址是不容許的。spa
同時,從上面的例子能夠看出,cout確實存在一些規律:指針
一、對於數字指針如int *p=new int; 那麼cout<<p只會輸出這個指針的值,而不會輸出這個指針指向的內容。
二、對於字符指針入char *p="sdf f";那麼cout<<p就會輸出指針指向的數據,即sdf f字符串
那麼,像&(p+1),因爲p+1指向的是一個地址,不是一個指針,沒法進行取址操做。編譯器
&p[1] = &p + 1,這樣取到的其實是從p+1開始的字符串內容。編譯
分析上面的程序:class
*pp = "abc";變量
p[] = "abc";
*pp指向的是字符串中的第一個字符。
cout << pp; // 返回pp地址開始的字符串:abc
cout << p; // 返回p地址開始的字符串:abc
cout << *p; // 返回第一個字符:a
cout << *(p+1); // 返回第二個字符:b
cout << &p[1];// 返回從第二個字符開始的字符串:bc