1. 程式人生 > >二重指標的理解

二重指標的理解

二重指標一般用的場合:

(1)二重指標指向一重指標的地址。

#include<stdio.h>

int main()

{

int a = 10;

int *P1;

int **P2;

P1 = &a;

P2 = &P1;

return 0;

}

 

(2)二重指標指向指標陣列的地址。

#include<stdio.h>

int main()

{

int *a[4];//指向整形變數的指標陣列

int **p;

p = a;//注意這裡為什麼可以這麼賦值?因為a是陣列首元素的地址,並且a的首元素為int *型別,所以a便是int *型別的地址,因此可以這麼賦值

}

 

int a=1,*p,**q;
p=&a; p存放變數a的地址
q=&p; q存放指標p的地址
**q=*p=a=1;
q是指標p的地址
*q是指標p的內容,即a的地址
**q是指標p指向區域的內容*p,*p=a

普通的指標存放變數的地址
指向指標的指標存放指標的地址

 

例:

int a=3, *p, **q;
p=&a;
q=&p;
這樣賦值後, *q就是p, **q就是a

 

例:
#include <stdio.h>
int main(void)
{
        char *q = "a";//"a"是一個字串,將"a"賦值給字元指標是把第一個字元的地址賦值給q,這句話相當於是:char *q;q="a" 
        char **p = &q;//這句話相當於是:char **p;p=&q;//二重指標p的值是指標q的地址 
        printf("%d\n", *p);//二重指標p加*號,是取內容,意思是指標q的內容,即字串a的地址 
        return 0;
}
//輸出結果是:一串數字,即地址,如果改成%s輸出,則輸出的是字元a,如果改成%c輸出,就要相應的修改引數為變數名,將*p改為:**p ,如下面的例子。
 

例:

#include <stdio.h>
int main(void)
{
        char c='a';
        char *q=&c;
        char **p = &q;//雙重指標
        printf("%c\n", **p);
        return 0;
}

 

例:

#include<stdio.h>
void F1(int *p)
{
    p++;
    *p = 9;
}
 
void F2(int **p)
{
    (*p)++;
}
//以上函式中,接收資料的參量都是p,而不會是*p或者**p
 
int* F3(int *p)
{
    p++;
    return p;
}
 
 
int main(void)
{
    int *p;
    int a[2] = { 4,5 };
    p = a;
    printf("1--------%d\n", *p);//開始值為4
 
    F1(p);
    printf("2--------%d\n", *p);//4
    //由於只是傳值,在子函式F1的內部改變複製品的值,並不會改變原品p的值
    //可以理解為用兩個變數指向同一個地址,即形參p和實參p指向同一個地址
    //其中形參p++,另外一個實參p並不會受影響
    //但是可以修改指標所指的值,如F1程式碼中將a[1]的值改為9;
    printf("2`-------%d\n", a[1]);//9
    
    F2(&p);
    printf("3--------%d\n", *p);//9
    //傳址,p=&p(指標的地址,即p是指向指標的指標),*p=*(&p)=p;
    //如果要修改指標p,則應該傳入指標p的地址(&p),此時進行*p++操作,其實是對實參指標p進行操作
 
    getchar(); getchar();
    return 0;
}
 
//這個例子說明:如果要在子函式中修改主函式傳過來的指標的指向,那麼主函式應該向子函式傳入指標的地址(而非指標本身);
//此時在子函式中進行*操作後可以獲得原來指標,而不是原來指標的複製品,之後可以根據需要修改指標。
//或者,將返回值型別改為指標型別,然後返回修改後的指標,給原來主函式的指標,如F3函式,此時在主函式中需要新增p=F3(p)程式碼。