C中二级指针与它指向的一级指针之间的秘密(深入++*pptr)
C語言里二級指針的意思是指向指針的指針,一級指針就是普通的指針,一個二級指針一定是對應著一個一級指針,那么二級指針和這個它對應的一級指針之間有什么秘密呢?
1. 首先明白在二級指針使用中?++*pptr 與 *pptr++ 之間的區別
首先申明一下,這里的pptr和標題中的一樣,都代表著指向指針的指針,是一個二級指針,所以用了兩個'p'來表示嘛。接下來看下面的代碼:
int main(int argc, char ** argv) {char * ar[5] = {"ruby", "java", "c++", "python", "js"};//定義一個含5個指針元素的指針數組 char ** pptr = ar;//定義一個二級指針,并初始化為ar printf("pptr = %p\n", pptr);printf("*pptr = %p\n", *pptr);printf("++*pptr = %p\n", ++*pptr); } 程序的輸出是:
第一行輸出都明白,第二行第三行地址卻僅僅加了1,說明第三行是"ruby"中u的地址。
那么換成*pptr++呢?
程序的輸出是:
我們發現,地址并沒有加1,那是因為在*pptr++中,pptr先和++結合,但是它所代表的是自增之前的地址,再用*運算符獲取到一個它對應的一級指針,所以打印出來的地址并沒有改變。而在++*pptr中,pptr先和*運算符結合,得到它所對應的一級指針,再對這個一級指針++,且是自增之后的地址,所得到的地址自然是加了1。
注意:*pptr++雖然地址沒有變,但是它仍然是遞增的,增了多少?實際上增的是二級指針,所以結果是404005。
2. 重點:深入++*pptr
先看下面一段代碼:
int main(int argc, char ** argv) {char * ar[5] = {"ruby", "java", "c++", "python", "js"};//定義一個含5個指針元素的指針數組 char ** pptr = ar;//定義一個二級指針,并初始化為ar char ** pptr_t = ar;//復制一份pptr printf("*++*pptr = %c\n", *++*pptr);printf("**pptr_t = %c\n", **pptr_t); } 輸出是多少呢?有人的答案是:*++*pptr = u,?**pptr_t = r
很遺憾,答案是錯的,不過答對了一半,*++*pptr = u 是正確的,那么**pptr_t又是多少呢?
肯定會有人疑問,pptr_t不是和pptr開始都一樣嗎,都是指針數組ar首元素的地址,pptr_t又沒有進行別的操作,**pptr_t的值不應該仍然是r嗎?
然而正確答案是:*++*pptr = u,?**pptr_t = u !
原因在于:++*pptr操作已經將pptr對應的那個一級指針*pptr自增了,直接改變了指針數組中第一個指針元素,它指向的不再是r而是u,當下一次訪問這個一級指針上的值時,即**pptr_t的值就是改變后的u了!
3. 應用:在處理命令行參數時遇到的問題
有些操作系統,包括UNIX和MS-DOS,讓用戶在命令行中編寫參數來啟動一個程序的執行。當在處理命令行參數時,有些程序允許用戶在一個參數中放入多個選項字母,例如下面的一個命令行:
prog -abc name1 name2 name3-abc是將-a,-b,-c三種選項字母結合在一起,同樣擁有三種選項。這交由下面的一段代碼來處理:
可以看到,程序中運用了++*argv,所以我們要注意的是,使用這種方式 ,命令行參數可能只能處理一次,因為指向參數的指針在內層循環中被破壞,如果多次處理參數,當你挨個訪問列表時,對每個需要增值的指針都做一份拷貝。
總結
以上是生活随笔為你收集整理的C中二级指针与它指向的一级指针之间的秘密(深入++*pptr)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 清华计算机系超算团队,关注 | 清华大学
- 下一篇: 产品之 2B、2C与2G