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(" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

指針與函數傳參的思考

系統 2024 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條評論
主站蜘蛛池模板: 欧美性爰视频 | 2018天天操天天干 | 国产精品视频成人 | 在线亚洲观看 | 国产理论最新国产精品视频 | 男人的天堂视频 | 色资源在线观看 | 成人网影 | 精品亚洲一区二区三区在线播放 | 一区二区中文字幕在线观看 | 欧美乱一级在线观看 | 国产成人性毛片 | 欧美一级毛片片免费 | 日韩精品欧美精品中文精品 | 国产精品视频全国免费观看 | 色网站在线看 | 77奇米影视| 九九在线精品视频播放 | 国产精品v一区二区三区 | 日韩欧美精品有码在线观看 | 久久天堂在线 | 裸身裸乳免费视频网站 | 日本一级毛片免费播 | 被公侵犯肉体中文字幕一区二区 | 奇米影音第四色 | 天海翼一区 在线播放 | 亚洲va高清中文字幕 | 国产精品国产自线在线观看 | 色综合久久中文字幕综合网 | 日本高清视频www夜色资源 | 97福利在线| 久草视频新 | 欧美精品福利在线视频 | 爱爱的免费视频 | 久草青青| 色女人综合 | 四虎在线影视在线影库 | 99久久免费中文字幕精品 | 久久久免费观成人影院 | 婷婷色人阁 | 亚洲综合免费视频 |