二级指针使用
指針就是指向內存的地址,那么對應的二級指針就是指向指針的指針,簡單點就是取指針的地址,二級指針的值是一個地址,具體可看下面的這個例子:
char ? c ? = ? 'a'; ? //一個字符型變量 ?? ?char ? *p; ? ? ? //p是一個指向char類型的指針 ?? ?p=&c; ? ? ? ? ? ? //現在p里存的是c的地址 ?? ?char ? **q; ? ? //q是一個二級指針 ?? ?q=&p; ? ? ? ? ? ? //q里存的是p的地址(p如前所述是個整數,所以p占有內存的一塊空 ?? ? ? ? ? ? ? ? ? ? ? ? ?//間,現在q就是指向這個空間的開始) ?? ?printf("%p",q); ? ? ? //p的地址 ?? ?printf("%p",*q); ? ? //c的地址 ?? ?printf("%c",**q); ? //a ?? ? ? ?int ? A[100]; ? //A是一個int ? *型的指針,指向一塊內存的開始(當然課本上把這種 ?? ? ? ? ? ? ? ? ? ? ? ? ? ?//指向預先分配的空間的指針叫做數組) ?? ?int ? B[100][100]; ? ? //B就是一個int ? **型的指針 ?? ? ? ?void ? F(int ? **p); ?? ? ? ?你可以這樣調用F ?? ?F(B); 1。用二級指針動態申請二維數組。?
void ? main()?
{?
? ? ? ? int ? m ? , ? n ? , ? **p;?
? ? ? ? scanf( "%d%d " ? , ? &m ? , ? &n);?
? ? ? ? p ? = ? (int ? **)malloc(m ? * ? sizeof(int ? *))?
? ? ? ? //C++中建議使用:p ? = ? new ? int* ? [m];?
? ? ? ? for(i ? = ? 0 ? ; ? i ? < ? m ? ; ? i++)?
? ? ? ? ? ? ? ? p[i] ? = ? (int ? *)malloc(n ? * ? sizeof(int)); ??
? ? ? ? ? ? ? ? //C++:p[i] ? = ? new ? int[n];?
}?
這樣就實現了二維數組的動態申請,因為一般數組聲明時,不允許下標是變量,所以如果想動態決定數組各維的大小,最好這樣做。?
2。使用二級指針傳遞參數,可以在函數內部修改一級指針。?
或許,你已經很熟悉通過傳遞一級指針,可以在函數內部修改實參指針指向的內容:如:?
void ? f(char ? *p)?
{?
? ? ? ? p[2] ? = ? 'a ';//由實參指向的函數外部的數組的內容就被改變了。?
? ? ? ? ……?
}?
但是,如果我們想改變實參本身呢?也就是說,我們連指針值都要改變,如果使用:?
void ? f(char ? *p)?
{?
? ? ? ? p ? = ? (char ? *)malloc(10 ? * ? sizeof(char))?
? ? ? ? //或C++中:p ? = ? new ? char[10];?
? ? ? ? ……?
}?
就不行了,因為在函數內部不能通過改變形參的值來改變實參(注意這里實形參是指針p,上面的那個函數并沒有改變形參,只是改變了形參指向的內容,只是由于形參和實參的值相同,也就是指向同一塊內存,所以也就是改變了實參指向的內容,這個時候就要用二級指針了)。?
void ? f(char ? **p)?
{?
? ? ? ? *p ? = ? new ? char[10];?
? ? ? ? *p[2] ? = ? 'a ';?
? ? ? ? ……?
}?
可以這樣說,傳入一個N級指針,就可以修改N-1級指針,原因就是C的參數傳遞是值傳遞的,直接修改形參根本改變不了實參,但可以改變行參指針指向的內容,而N級指針指向的內容就是一個N-1級指針(你可以把非指針變量理解為0級指針),另外,你可能感覺這樣使用似乎有問題,因為原先的內存空間沒有釋放,是的,這只是個為了說明問題的簡化了的例子,實際的應用場合要比這合適的多。?
最后,指針是C/C++語言的精華,但理解指針還是應該從指針本身去理解,二級指針只是指針的一種,不應該在這里鉆牛角尖,多級指針其實還是指針,只不過它指向的內容內容仍是指針而已。
void ? main()?
{?
? ? ? ? int ? m ? , ? n ? , ? **p;?
? ? ? ? scanf( "%d%d " ? , ? &m ? , ? &n);?
? ? ? ? p ? = ? (int ? **)malloc(m ? * ? sizeof(int ? *))?
? ? ? ? //C++中建議使用:p ? = ? new ? int* ? [m];?
? ? ? ? for(i ? = ? 0 ? ; ? i ? < ? m ? ; ? i++)?
? ? ? ? ? ? ? ? p[i] ? = ? (int ? *)malloc(n ? * ? sizeof(int)); ??
? ? ? ? ? ? ? ? //C++:p[i] ? = ? new ? int[n];?
}?
這樣就實現了二維數組的動態申請,因為一般數組聲明時,不允許下標是變量,所以如果想動態決定數組各維的大小,最好這樣做。?
2。使用二級指針傳遞參數,可以在函數內部修改一級指針。?
或許,你已經很熟悉通過傳遞一級指針,可以在函數內部修改實參指針指向的內容:如:?
void ? f(char ? *p)?
{?
? ? ? ? p[2] ? = ? 'a ';//由實參指向的函數外部的數組的內容就被改變了。?
? ? ? ? ……?
}?
但是,如果我們想改變實參本身呢?也就是說,我們連指針值都要改變,如果使用:?
void ? f(char ? *p)?
{?
? ? ? ? p ? = ? (char ? *)malloc(10 ? * ? sizeof(char))?
? ? ? ? //或C++中:p ? = ? new ? char[10];?
? ? ? ? ……?
}?
就不行了,因為在函數內部不能通過改變形參的值來改變實參(注意這里實形參是指針p,上面的那個函數并沒有改變形參,只是改變了形參指向的內容,只是由于形參和實參的值相同,也就是指向同一塊內存,所以也就是改變了實參指向的內容,這個時候就要用二級指針了)。?
void ? f(char ? **p)?
{?
? ? ? ? *p ? = ? new ? char[10];?
? ? ? ? *p[2] ? = ? 'a ';?
? ? ? ? ……?
}?
可以這樣說,傳入一個N級指針,就可以修改N-1級指針,原因就是C的參數傳遞是值傳遞的,直接修改形參根本改變不了實參,但可以改變行參指針指向的內容,而N級指針指向的內容就是一個N-1級指針(你可以把非指針變量理解為0級指針),另外,你可能感覺這樣使用似乎有問題,因為原先的內存空間沒有釋放,是的,這只是個為了說明問題的簡化了的例子,實際的應用場合要比這合適的多。?
最后,指針是C/C++語言的精華,但理解指針還是應該從指針本身去理解,二級指針只是指針的一種,不應該在這里鉆牛角尖,多級指針其實還是指針,只不過它指向的內容內容仍是指針而已。
總結
- 上一篇: 20165203 2017-2018-2
- 下一篇: LM算法+推导+C++代码实践