天天看點

指針和引用(4)指向指針的指針

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]