指標巢狀指標 拷貝 二級指標的作用詳解

2021-10-11 13:31:09 字數 2606 閱讀 3245

一、概念

在如下的a指向b、b指向c的指向關係中:

首先c是"一段內容",比如你用malloc或者new分配了一塊記憶體,然後塞進去"一段內容",那就是c了。c的起始位址是0x00000008。

b是乙個指標變數,其中存放著c的位址,但是b也要佔空間的啊,所以b也有位址,b的起始位址是0x00000004,但是b記憶體中存放的是c的位址,所以b裡面的內容就是0x00000008。

那麼到此為止都比較好理解:

b= 0x00000008; //b的內容

*b = "一段內容"; //b解引用,也就是b指標指向的c的值

&b = 0x00000004; //b取位址,b的位址是0x00000004

那麼,再來看a:

a是二級指標變數,其中存放著b的位址0x00000004,a也有位址,是0x00000000;

*a = b= 0x00000008; //a解引用也就是b的內容

**a = *b = "一段內容"; //b解引用,也就是b指標指向的c的值

a = &b = 0x00000004; //a存的是b的位址,b的位址是0x00000004

&a = 0x00000000; //a取位址

二、使用

二級指標作為函式引數的作用:在函式外部定義乙個指標p,在函式內給指標賦值,函式結束後對指標p生效,那麼我們就需要二級指標。

看看下面一段**:有兩個變數a,b,指標q,q指向a,我們想讓q指向b,在函式裡面實現。

1.先看看一級指標實現

#include

using namespace std;

int a= 10;

int b = 100;

int *q;

void func(int *p)

cout<

cout<

cout<

cout<

cout<

return 0;

這麼寫有什麼問題?為什麼*q不等於100?我們看一下輸出便知:

&a=0032f000,&b=0032f004,&q=0032f228

*q=10,q=0032f000,&q=0032f228

func:&p=0018fd24,p=0032f000

func:&p=0018fd24,p=0032f004

*q=10,q=0032f000,&q=0032f228

我們看輸出:

note:1->a,b,q都有乙個位址.

note:2->q指向a.

note:3->我們發現引數p的位址變了,跟q不一樣了,是的引數傳遞是製作了乙個副本,也就是p和q不是同乙個指標,但是指向的位址0x0032f000(a的位址)還是不變的.

note:4->p重新指向b.

note:5->退出函式,p的修改並不會對q造成影響。

結論:編譯器總是要為函式的每個引數製作臨時副本,指標引數p的副本是 p,編譯器使 p = q(但是&p != &q,也就是他們並不在同一塊記憶體位址,只是他們的內容一樣,都是a的位址)。如果函式體內的程式修改了p的內容(比如在這裡它指向b)。在本例中,p申請了新的記憶體,只是把 p所指的記憶體位址改變了(變成了b的位址,但是q指向的記憶體位址沒有影響),所以在這裡並不影響函式外的指標q。

這就需要二級指標操作:

2.二級指標操作

#include

using namespace std;

int a= 10;

int b = 100;

int *q;

void func(int **p) //2

cout<

cout<

cout<

cout<

cout<

return 0;

這裡只改了三個地方,變成傳二級指標。我們再看:

因為傳了指標q的位址(二級指標**p)到函式,所以二級指標拷貝(拷貝的是p,一級指標中拷貝的是q所以才有問題),(拷貝了指標但是指標內容也就是指標所指向的位址是不變的)所以它還是指向一級指標q(*p = q)。在這裡無論拷貝多少次,它依然指向q,那麼*p = &b;自然的就是 q = &b;了。

3.再看乙個例子:

我們**中以二級指標作為引數比較常見的是,定義了乙個指標myclass *ptr=null,在函式內對指標賦值*ptr=malloc(...),函式結束後指標依然有效.這個時候就必須要用二級指標作為引數func(myclass **p,...),一級指標為什麼不行上面說了。

void my_malloc(char **s)

*s=(char*)malloc(100);

void main()

char *p=null;

my_malloc(&p);

//do something

if(p)

free(p);

這裡給指標p分配記憶體,do something,然後free(p),如果用一級指標,那麼就相當於給乙個p的拷貝s分配記憶體,p依然沒分配記憶體,用二級指標之後,才對p分配了記憶體。

二級指標,指向指標的指標

test 函式的語句getmemory str,200 並沒有使str 獲得期望的記憶體,str 依舊是null,為什麼?指標傳遞 void getmemory char p,int num void test void 解釋 毛病出在函式getmemory 中,編譯器總是要為函式的每個引數製作臨時...

二級指標,指向指標的指標

我們先來看乙個例子 假設我們有第三個變數時 c b c的型別顯然是乙個指標,變數b是乙個 指向整形的指標 所以任何指向b的型別必須是指向 指向的指標 的指標,更通俗的來講就是指標的指標。它合法嗎?指標變數和其他變數一樣,佔據記憶體中某個特定的位置,所以用 操作符取得他的位址是合法的。這個變數宣告為 ...

二級指標(指向指標的指標)

指標可以指向乙份普通型別的資料,例如 int double char 等,也可以指向乙份指標型別的資料,例如 int double char 等。如果乙個指標指向的是另外乙個指標,我們就稱它為二級指標,或者指向指標的指標。假設有乙個 int 型別的變數 a,p1是指向 a 的指標變數,p2 又是指向...