1.知識點
(1)在程式中可以聲明指向任何資料類型的指針,指針也可以指向指針類型,成為指向指針的指針。下面是一個使用例子
1 int a=10,b=20;
2 int *q=&a;
3 int **p=&q;
4 **p=30;
(2)如果想通過指針在被調函數中修改主調函數的變量,必須将主調函變量(務必确定該變量的類型,有時候可能變量本身就是指針,這時候形參就需要是指針的指針了)的位址作為參數,在被調函數中修改主調函數指向的内容。
2.面試題
2.1指針作為參數的常見錯誤
1 int find(char *s, char ch, char *sub) {
2 for (int i = 0; *(s + i) != '\n'; i++) {
3 if (*(s + i) == ch) {
4 sub = s + i + 1;
5 return i;
6 }
7 }
8 return 0;
9 }
10
11 int main(int argc, char *argv[]) {
12 char fullName[] = {"Jordan#Michale"};
13 char *givenName=fullName;
14
15 int cnt = find(fullName, '#', givenName);
16 cout << givenName << "has a" << cnt << "characters 'family name" << endl;
17
18 getchar();
19 return 0;
20 }
重點知識點:(1)如果想通過指針在被調函數中修改主調函數的變量,必須将主調函變量的位址作為參數,在被調函數中修改主調函數指向的内容。
(2)通過指針傳遞參數時,最大的忌諱就是以為隻要參數是指針就萬事大吉了。實際上,應該首先确定要修改的變量的類型,然後再将其位址作為參數。如果要修改的變量本身就是指針,就應該将該指針的位址作為參數,此時的形參類型是指向指針的指針。
以上第三個參數的指向的改變并不能帶來實參的改變,正确答案如下:
1 int find(char *s, char ch, char **sub) {
2 for (int i = 0; *(s + i) != '\n'; i++) {
3 if (*(s + i) == ch) {
4 *sub = s + i + 1;
5 return i;
6 }
7 }
8 return 0;
9 }
10
11 int main(int argc, char *argv[]) {
12
13 char fullName[] = {"Jordan#Michale"};
14 char *givenName=NULL;
15
16 int cnt = find(fullName, '#', &givenName);
17 cout << givenName << " has a " << cnt << " characters 'family name" << endl;
18
19 getchar();
20 return 0;
21 }
2.2指向指針的指針和二維數組的差別
1 int main(){
2 int a[2][3]={{1,2,3},{4,5,6}};
3 int **p=a;
4 cout<<**p<<endl;
5 getchar();
6 return 0;
7 }
解析:p是指向指針的指針(類型是int **),a<=>&a[0],a[0]是一個一維數組(相當于對一維數組名a[0]取位址,它應該指派給int *[3])。是以左邊是一個指向指針的指針,右邊是一個指向數組的指針,兩邊類型不同。如果想編譯通過,應該定義一個指向數組的指針,修改如下:
1 int (*p)[3]=a;
小技巧:判斷變量的類型:
變量的類型在聲明之初就已經确定了,在程式中隻要将聲明語句中變量名去掉,剩下的部分就是變量的類型。如下:
1 int **p的類型是:int**
2 int a[2][3]的類型是:int[2][3]
3 const int(const *p)[3]的類型是:const int(cosnt *)[3]