本文是自己學習所做筆記,歡迎轉載,但請注明出處:http://blog.csdn.net/jesson20121020
指針是一個特殊的變量,表示一個地址,而地址可以上減去或加上一個整數,從而可以表示新的地址.
下面通過一段代碼來分析指針的算術運算:
#include執行結果:int main(){ int i; char str[]={'a','b','c','d','e'}; int *p = str; char *q = str; q++; p++; printf("數組str的首地址:%x\n",str); printf("指針q指向的內在區:%x\n",q); printf("指針p指向的內存區:%x\n",p); printf("數組的第一個元素的值:%c\n",*str); printf("數組的第一個元素的值:%c\n",*p); //遍歷數組第一種方法,下標法 printf("遍歷數組第一種方法,下標法:"); for(i = 0 ;i < sizeof(str);i++) printf("%c",str[i]); //遍歷數組第二種方法,數組名指針法 printf("\n遍歷數組第二種方法,數組名指針法:"); for(i = 0 ;i < sizeof(str);i++) printf("%c",*(str+i)); //遍歷數組第三種方法,指針法 q = str; printf("\n遍歷數組第三種方法,指針法:"); for(i = 0 ;i < sizeof(str);i++) printf("%c",*q++); }
可以看出,數組的首地址為163c4730.通過上節的指針的概念和四個要素,很容易得知,指針q的類型為char*,且指針q指向的類型為char; char *q = str;的作用是將數組str的首地址賦給指針q,也就是說指針q的值或q指向的內存區就是數組str的首地址. 接下來,指針q自加1,這時,編譯器是這樣處理的,它把指針q的值加上了sizeof(char),也就是在原來的地址的基礎上向後移動了一個字節,即指針q的指向的內存區為163c4730+1=163c4731.
同理,指針p的類型為int*,且指向的類型為int, int *p = str; 作用也是將數組的首地址賦給指針p,p++,編譯器將把指針p的值加上了sizeof(int),也就是在原來的基礎上向後移動了4個字節,即指針p指向的內存區為163c4734,所以指針p在自加前,是指向數組第0號單元開始的四個字節,在自加1後指向了數組第四號單元開始的四個字節。
因此,判斷指針向後移動的多少位時,需要判斷指針指向的類型。
也可以用指針來遍歷數組,如上述代碼,可以使用數組名,因為這裡的數組名就是指向了數組的第0號單元,如果在此基礎上加上一個偏移量,就可以訪問數組的其他元素,因此,可以用數組名+偏移量來遍歷數組。同理,另設一個指針指向數組的第0號單元,每次指針自加1,就可以遍歷整個數組,這裡要注意,指針的所指向的類型,要和數組的元素類型要一致,所以上述代碼中用指針q來遍歷數組,而不是用指針p來遍歷。
當然,如果指針減去一個整數,處理過程和加上一個過程類似,只是向前移動了,而不是向後移動。
總結一下,一個指針ptrold加上一個整數n後,結果是一個新的指針ptrnew,ptrnew的類型和ptrold的類型相同,ptrnew所指向的類型和ptrold所指向的類型也相同。ptrnew的值將比ptrold的值增加了n乘sizeof(ptrold所指向的類型)個字節。就是說,ptrnew所指向的內存區將比ptrold所指向的內存區向高地址方向移動了n乘sizeof(ptrold所指向的類型)個字節。一個指針ptrold減去一個整數n後,結果是一個新的指針ptrnew,ptrnew的類型和ptrold的類型相同,ptrnew所指向的類型和ptrold所指向的類型也相同。ptrnew的值將比ptrold的值減少了n乘sizeof(ptrold所指向的類型)個字節,就是說,ptrnew所指向的內存區將比ptrold所指向的內存區向低地址方向移動了n乘sizeof(ptrold所指向的類型)個字節。