原文地址:http://www.cnblogs.com/jeakon/archive/2012/05/27/2816809.html
代碼中的int * i就是我們關注的焦點。它是一個指向int指針。也就是說:i指向一個內存地址,從這個地址開始存儲了一個數據。int * i中的int標明應該使用int類型(長度為sizeof(int)個字節)來從這個地址取數據,也就是說要一次取sizeof(int)個byte的數據來拼成最後的結果。最後一個例子也證明了這一點:如果我們強制用unsigned char的大小的數據類型來對這個地址操作,就只能取出數據的一部分。反過來說,如果用較大數據類型來取實際存儲較小數據類型的數據,就有可能越界操作內存,取回一些雜亂的內容或導致系統崩潰。int b[]這個數組,標明有一組數,放在以&b開始地址的內存空間內,每個元素占用了sizeof(int)個byte的內存單元;如果有類似於i=&b;i++;的操作,i的值就每次遞增sizeof(int)而不是1,這樣確保了i每次都能恰好取回一個正確的int。
同理,char * c也是如此。如果我們定義了一個char *的變量c,那麼c也只不過是一個指向內存中某個地址的指針而已。之所以標明它是char *的類型,就是說要以sizeof(char)為單位去內存中取數。所以,我們應該稱呼char * c為指向char類型的指針——而不是說c就是字符串。為什麼傳一個char *指針給printf(),strlen()之類的函數,它就能把它當作一個字符串來處理呢?沒錯,我們不是定義了'\0'來表示一個"字符串"的終結麼?我們只需從起始地址不斷累加,遍歷字符數組的每一個元素,直到找到一個'\0'為止,就算是處理一個字符串了——從起始地址到'\0'為止的字符數組元素構成一個“字符串”,這就是C語言設計字符串的原理。
所以,當一個函數要求傳入一個char *的參數,並不一定這個參數就一定是字符串(以'\0'結尾的字符數組),char *只是一個字符指針而已,它僅僅提供了一個內存地址和每次遍歷元素的偏移量而已。究竟函數對傳入的參數有什麼要求,還要視函數的具體實現而定。(我想ANSI C應該對參數有所要求和規定,可惜偶沒有ANSI C文件,無法參考。 )C語言一般約定是用char * str來表示以'\0'結尾的字符數組,但是由於某些實現上的效率的考慮,往往沒有嚴格遵守這個約定。C語言的設計理念中沒有強調使用者一定要使用遵守這個約定,不遵守這個約定也不違背C語言的基本語法規則。這或許可以看作是C語言和創造和使用它的黑客群體崇尚自由的一種特色、一種精神文化吧。
trackback:http://blog.vckbase.com/smileonce/archive/2005/06/26/8330.html