structA{inta;};structAg_ta={.a=1,};structAg_tb={.a=2,};voidfun1(structA*p1){p1->a=3;}voidfun2(structA*p2){p2=}voidfun3(structA**p3){*p3=}intmain(){structA*p=printf("p->a=%d\n",p->a);fun1(" />

欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

指針與函數傳參的思考

系統 2102 0

先看代碼,這個代碼很簡單,看你能不能準確地說出答案。

#include <stdio.h>

?

struct A {

??????? int a;

};

?

struct A g_ta = {

??????? .a = 1,

};

?

struct A g_tb = {

??????? .a = 2,

};

?

void fun1(struct A * p1)

{

??????? p1->a = 3;

}

?

void fun2(struct A * p2)

{

??????? p2 = &g_tb;

}

?

void fun3(struct A ** p3)

{

??????? *p3 = &g_tb;

}

?

int main()

{

??????? struct A *p = &g_ta;

??????? printf("p->a = %d\n",p->a);

?

??????? fun1(p);

??????? printf("p->a = %d\n",p->a);

?

??????? fun2(p);

??????? printf("p->a = %d\n",p->a);

?

??????? fun3(&p);

??????? printf("p->a = %d \n",p->a);

??????? return 0;

}

?

gcc編譯,運行結果如下:

p->a = 1

p->a = 3

p->a = 3

p->a = 2

對了嗎?如果你對了,說明你對指針和函數參數傳遞已經理解。

如果你和我一樣,答案和打印結果相悖,繼續看。

第一行和第二行輸出應該沒問題,很簡單的,是通過指針方式進行傳值的,所以改變形參的值,實參也會跟著改變。

再看第三行輸出,為什么經過fun2 后值不是p->a = 2,而是p->a = 3?fun2不也是通過指針方式來進行傳值的嗎?怎么沒有改變p的值呢?

再看第四行輸出,p->a = 2?怎么形參為指針的指針就對了呢?

?

帶著疑問看下面:

首先不要覺得指針是個很神奇的東西,我之前一直對指針不理解,或者是理解不透徹,這兩天在寫電子書的代碼,感覺對指針這個東西有了些頓悟,我可以告訴你指針就是一個變量,他和別的變量(比如int,char)沒有什么本質的區別,都是一個內存A里存放變量的值!唯一區別就是指針被多設計了一個 * 號,該 * 號的意思就是將這個內存A里面的值當成另一個內存B的地址,并取出這個內存B的值,說到這里,這就是指針的全部!

下面是函數參數傳遞,回頭看我說的一句話“通過指針方式進行傳值的,所以改變形參的值,實參也會跟著改變”,這句話其實是障眼法,學C語言的時候老師就告我們,值傳遞方式,形參改變不能影響實參,而地址傳遞傳遞是可以的,這句話不能算錯,但是不能說對,地址傳遞方式形參改變確實能影響實參,但是也是要看改變的是什么,影不影響實參是有道理的!

為了更好得說明,我將內存抽塊象成如下小方塊,一個方塊代表一塊內存。

另注,1. 我將一個結構體看成一塊小內存,2. 變量的內存地址是我假設的。3.地址就是指此塊內存的地址,每塊內存都有自己地址。


變量

地?? 址


現在開始分析代碼:

?

首先申明兩個struct A全局變量,其內存模型如下,(地址是我假設的,以下都是,不再贅述) ??

? ? ?g_ta

g_ta

1

0x10

?

?

? ? ??

? ? ?g_tb

g_tb

2

0x11

?

?

?

在main數里面申明了結構體A指針,其指向g_ta,其內存模型如下

? ? ? ? P

p

0x10

0x50

?

?

?

注意看,p的值就是 0x10,g_ta的地址,沒什么特別的。


現在開始分析fun2,fun2弄懂了fun1自然就理解了,首先p經過了fun1之后,將g_ta里面的值變成了3,所以,現在他們內存情況如下:(這三塊內存方格是分開的,貼到這里就連在一起了,以下同樣,不再贅述。。。)

? ? ? g_ta ? ? ? ? ? ?g_tb ? ? ? ? ? ?p

g_ta

3

0x10

g_tb

2

0x11

p

0x10

0x50

?

??????

?

調用fun2(p);

?????? ? | |

?????? ? \/?

void fun2(struct A * p2)

{

??????? p2 = &g_tb;

}


進入函數fun2,會生成一個和形參類型相同副本,其將實參值拷貝,即結構體指針p2,其內存模型如下 ? ? ? ? ? ? ? ? ? ??

? ? ? ? p ? ? ? ? ? ? ? ?p2

p

0x10

0x50

p2

0x10

0xa0

?

?

?

可以看到,他和指針p的不同就是內存地址不同,而他們的值是相同的,都表示g_ta的地址。


p2 = &g_tb;

這句就是將g_tb的地址賦值給p2,那么p2內存模型就會變成如下:

? ? ? ? ?p ? ? ? ? ? ? ? ?p2

p

0x10

0x50

p2

0x11

0xa0

?

?

?

好了,p2的值不是改變了嗎,p2確實指向了g_tb了啊?怎么打印得不對呢?哈哈,你再看看,printf打印得是p啊,p指向的還是是g_ta,當然輸出的是3了啊!p2在退出fun2時候就自動銷毀了!


跟著內存模型來看,很容易理解吧,那下面繼續來看fun3,fun3為什么就能正確地打印出g_tb的值呢?繼續用內存模型來分析:

此時內存情況如下:

? ? ? ?g_ta ? ? ? ? ?g_tb ? ? ? ? ? ? ?p

g_ta

3

0x10

g_tb

2

0x11

? p?

0x10

0x50

?

??????

? ?

執行函數fun3(&p);

????????????? ?? | |

????????????? ?? \/

void fun3(struct A ** p3)

{

??????? *p3 = &g_tb;

}

經過fun3,將p的地址 0x50傳給了fun3,這個0x50沒有什么特別得,他就是一個數值,對于fun3來說他根本不知道這個0x50代表什么意思!所以我們就要告訴fun3,這個0x50是個內存地址,這個地址內存里面的內容仍然是一個地址!轉變成C語言來理解就是要設計一個形參,這個形參能夠進行兩次取內存值的操作,好,struct A ** p3就應運而生了!

?p3:指針的指針,感覺好復雜啊!其實一點都不復雜,說到底p3就是一個指針嘛,不過他指向的內存里面的數據也是指針類型罷了,既然p3還是一個指針那再來看看他的內存模型

? ? ?g_ta ? ? ? ? ? ?g_tb ? ? ? ? ? ?p ? ? ? ? ? ? ? ?? p3

g_ta

3

0x10

g_tb

2

0x11

p

0x10

0x50

P3

0x50

0xa1

????????????????????

?

? ? ??

進過fun3,實參傳遞了p的地址0x50給p3,所以p3的值就是0x50,看清楚了!


執行*p3= &g_tb;

*p3就是取地址為0x50內存的值,地址為0x50的內存里面存放是誰的值啊?

對!就是p的值,所以這條代碼其實改變了的是p的值,將g_tb的值賦給了p!

? ? g_ta ? ? ? ? ? ? ?g_tb ? ? ? ? ? ? ?p???????????????? p3

g_ta

3

0x10

g_tb

2

0x11

p

0x11

0x50

P3

0x50

0xa1

????????????????????

?

? ? ??

好了,基本都已經清楚了,退出fun3,p3銷毀,打印p指向的值,就是p->a = 2

分析已經結束了,還有fun1,可以自己用這種內存模型方法來自己分析一下 :)

?

總結:想要改變指針指向的內容,就傳指針給函數,想要改變指針的值,那就得傳遞指針的地址了,相應的函數參數就要設計成指針的指針了!

?

?

指針與函數傳參的思考


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久精品国产99久久6动漫亮点 | 亚洲 欧美 日韩 在线 | 色噜噜狠狠色综合欧洲 | 免费特黄一级欧美大片在线看 | 免费黄色大片在线观看 | 久操国产在线 | 中国女警察一级毛片视频 | 性欧美tube 精品 | 欧美一区二区免费电影 | 色午夜日本 | 国产精品色综合 | 国产亚洲一区二区三区在线观看 | 一区二区三区不卡免费视频97 | 成人免费xxxxx在线观看 | 日本一区二区三区免费高清在线 | 一级做受毛片免费大片 | 中文在线а√在线8 | 孕妇体内谢精满日本电影 | 久久一级视频 | 精品国产影院 | 久久69精品久久久久久国产越南 | 伊人久操 | 天天操天天插天天干 | 夜班护士在线观看 | 中文字幕精品一区二区三区精品 | 亚洲 久久 | 九九视频高清视频免费观看 | 色屁屁影院网站入口 | xxx视频 | 国产大尺度吃奶无遮无挡网 | 久久人人爽人人爽人人片va | 超碰97人人艹 | 国产日韩一区二区三免费高清 | 国产欧美精品一区二区三区 | 日本黄色三级网站 | 久久久久综合 | 久热精品视频 | 亚洲人精品| 丁香婷婷色综合亚洲小说 | 国产欧美一区二区三区免费看 | 奇米奇米 |