標籤:
轉自:http://blog.csdn.net/snowq/archive/2008/01/17/2050129.aspx
最近寫了一個小程式,遇到一點小問題,是關於指向字串的指標的。由此一發不可收拾,好奇心驅使我決定研究一下指標的初始化和賦值規則。略有所得之後,執筆記下,以備後用。
1、指標的初始化
初看起來,指標的初始化和賦值好像很混亂,又是*,又是&,時不時又出來一個數組。其實總結起來很簡單:
int *p;
int a=25;
int b[10];
int *m=&a;
int *n=b;
int *r=&b[0];
指標的定義如上所示,以*打頭的變數代表該變數為指標變數。
指標初始化時,“=”的右運算元必須為記憶體中資料的地址,不可以是變數,也不可以直接用整型地址值(但是int *p=0;除外,該語句表示指標為空白)。此時,*p只是表示定義的是個指標變數,並沒有間接取值的意思。
Int *s=15;
Int *s={2,3,5};
Int *s=a;
以上這三種初始化方式都是錯誤的。
2、指標的賦值
P=m;
P=&a;
P=b;
*p=25;
*p=a;
*p=b[4];
指標相關的賦值,“=”的左運算元可以是*p,也可以是p。
當“=”的左運算元是*p時,改變的是p所指向的地址存放的資料;當“=”的左運算元是p時,改變的是p所指向的地址。
數組的變數名b表示該數組的首地址,因此p=b;也是正確的。
3、 “特殊情況”
前面講到了,指標的初始化必須使用變數地址,而不可以直接使用變數。
那麼,下面這個又如何解釋呢:
Char *cp=”abcd”;
其實,這個初始化過程,是將指標cp指向字串的首地址,而並不是傳遞字串的值。因為,在C語言裡面,沒有整體處理一個字串的機制。
所以,我們的標題“特殊情況”加上了一個引號,因為,它實際上也是以變數地址初始化的指標,“特殊情況”並不特殊。
由此引出,如何使用字串對指標賦值呢?只有採用下面這種方式:
Cp=”mnop”;
型如*cp=”mnop”;這樣的語句是錯誤的。原因如上所述,字串常量傳遞的是它的首地址。
另外,這個初始化過程還有另一層隱含的意思:”abcd”是字串常量,在初始化過程中並沒有發生字串的複製,而只是簡單的將指標指向該字串常量,因此,不可以通過*cp修改該字串的值,因為該字串為常量。當然,我們可以使用“cp=”來修改指標指向的字串,指標本身並不是常量。
如果試圖通過指標*cp來修改該字串,會出現什麼結果,答案是未定義的,要視不同的編譯器而定。至少有一點可以確定,在編譯階段,編譯器不會報錯,因為*cp不是常量,所以對*cp賦值並沒有什麼語法錯誤。但是有些編譯器,比如VC,會在運行時拋出異常:寫入位置 0x00415768(cp指向的地址) 時發生存取違規!
這點上與char ca[]=”abcd”;是不同的,通過ca[x]可以修改字串中的資料。
4、 C語言的經典著作
最後,順便提一下C語言的經典好書。主要有下面幾本:
《The C Programming Language》(C程式設計語言),C語言之父所著,短短二百多頁就可以把C語言的各種細節描繪得清清楚楚,不可不謂經典。比起國內四五百頁,卻不知其所云的C語言程式設計來,真是天壤之別。
《C專家編程》,該書第一版於2002年由人民郵電出版社引進,之後曾一度絕版。最近傳出要再版的訊息,令人不能不興奮。同時,這本書也是我近期想要收藏的。
指標賦值的問題【轉】