日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

图解C/C++中函数参数的值传递、指针传递与引用传递

發(fā)布時(shí)間:2025/5/22 c/c++ 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图解C/C++中函数参数的值传递、指针传递与引用传递 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

因?yàn)橐恢睂?duì)這幾種函數(shù)參數(shù)的傳遞方式理解的不是很透徹,花了一段時(shí)間仔細(xì)捋清了他們之間的區(qū)別。這個(gè)問(wèn)題也是編程初級(jí)階段會(huì)經(jīng)常遇到的問(wèn)題,也是有可能在面試中遇到的基本問(wèn)題,在此進(jìn)行了簡(jiǎn)單的總結(jié)一下,一是加深自己的理解,二是希望幫助遇到同樣問(wèn)題的同學(xué),希望能幫你們快速透徹的理解他們。

? ? 主要以實(shí)現(xiàn)交換兩個(gè)整形值(老生常談的話題了)為載體進(jìn)行透徹的說(shuō)明,我們的主要方法就是利用最基本的輸入輸出功能來(lái)看函數(shù)執(zhí)行前和執(zhí)行后,參數(shù)地址和值的變化來(lái)看函數(shù)“做了什么事情”。

? ? 針對(duì)每一個(gè)不同的函數(shù),主要從展現(xiàn)了如下幾個(gè)方面:(1)函數(shù)開(kāi)始執(zhí)行前的參數(shù)的狀態(tài),包括參數(shù)的地址和值(2)函數(shù)實(shí)現(xiàn)了什么樣的操作(3)函數(shù)執(zhí)行后的參數(shù)的狀態(tài)。最后我們簡(jiǎn)單的總結(jié)了這5個(gè)函數(shù)為什么有的能實(shí)現(xiàn)目的;而有的不能實(shí)現(xiàn)目的,進(jìn)一步解釋了這些不能實(shí)現(xiàn)目的函數(shù)他們到底做了哪些事情(通過(guò)前后參數(shù)狀態(tài)的變化來(lái)反映)。

? ? 在main函數(shù)中,我們首先顯示出實(shí)參的地址,當(dāng)將實(shí)參傳入到函數(shù)中,我們顯示被調(diào)函數(shù)中變量的地址。只要被調(diào)函數(shù)中變量地址和實(shí)參的地址一樣,我們認(rèn)為是直接操作變量而不是操作變量的”副本“;如果被調(diào)函數(shù)中變量的地址與實(shí)參地址不同,則認(rèn)為是對(duì)實(shí)參進(jìn)行了一次拷貝,即新建了一個(gè)實(shí)參的”副本“,這個(gè)”副本“的和實(shí)參值一樣,被調(diào)函數(shù)在后續(xù)的操作中都是對(duì)這個(gè)”副本“進(jìn)行操作的,而副本的改變和原實(shí)參無(wú)任何關(guān)系。當(dāng)被調(diào)函數(shù)結(jié)束后,該副本做為局部變量而結(jié)束生命周期。

首先看一下5個(gè)常見(jiàn)交換值的函數(shù)(有的能實(shí)現(xiàn),有的不能實(shí)現(xiàn)交換目的)。依據(jù)上述原理,如果交換函數(shù)中是對(duì)真正實(shí)參(數(shù)據(jù)或指針)的操作,則認(rèn)為能實(shí)現(xiàn)交換目的;而如果只是對(duì)實(shí)參副本進(jìn)行交換操作,則認(rèn)為不能達(dá)到交換目的。

本文未從理論上進(jìn)行過(guò)多的論述,需要的同學(xué)可以自行搜索一下相關(guān)資料。

[cpp]?view plaincopy
  • <span?style="font-family:SimSun;">//交換兩個(gè)數(shù)字的值,由于函數(shù)中較多的使用了cout來(lái)顯示相關(guān)的值,所以使原本簡(jiǎn)單的函數(shù)看起來(lái)很長(zhǎng)</span><span?style="font-family:SimHei;">。</span>??
  • ??
  • void?change0(int?a1,int?a2)??
  • {??
  • ????//這個(gè)函數(shù)不能實(shí)現(xiàn)目的??
  • ????cout<<"change0?執(zhí)行前:"<<endl;??
  • ????cout<<"&a1="<<&a1<<",&a2="<<&a2<<endl;??
  • ????cout<<"a1="<<a1<<",a2="<<a2<<endl;??
  • ??????
  • ????int?temp=a1;??
  • ????a1=a2;??
  • ????a2=temp;??
  • ??
  • ????cout<<"change0?執(zhí)行后:"<<endl;??
  • ????cout<<"&a1="<<&a1<<",&a2="<<&a2<<endl;??
  • ????cout<<"a1="<<a1<<",a2="<<a2<<endl;??
  • }??
  • [cpp]?view plaincopy
  • void?change1(int?*a1,int?*a2)??
  • {??
  • ????//能實(shí)現(xiàn)目的??
  • ????cout<<"change1?執(zhí)行前:"<<endl;??
  • ????cout<<"&a1="<<&a1<<",&a2="<<&a2<<endl;??
  • ????cout<<"*a1="<<*a1<<",*a2="<<*a2<<endl;??
  • ????cout<<"a1="<<a1<<",a2="<<a2<<endl;??
  • ??
  • ????int?temp;??
  • ????temp=*a1;??
  • ????*a1=*a2;??
  • ????*a2=temp;??
  • ??
  • ????cout<<"change1?執(zhí)行后:"<<endl;??
  • ????cout<<"&a1="<<&a1<<",&a2="<<&a2<<endl;??
  • ????cout<<"*a1="<<*a1<<",*a2="<<*a2<<endl;??
  • ????cout<<"a1="<<a1<<",a2="<<a2<<endl;??
  • }??
  • ??
  • void?change2(int?*a1,int?*a2)??
  • {??
  • ????//這個(gè)函數(shù)不能實(shí)現(xiàn)目的??
  • ????cout<<"change2?執(zhí)行前:"<<endl;??
  • ????cout<<"&a1="<<&a1<<",&a2="<<&a2<<endl;??
  • ????cout<<"*a1="<<*a1<<",*a2="<<*a2<<endl;??
  • ????cout<<"a1="<<a1<<",a2="<<a2<<endl;??
  • ??
  • ????int?*temp=a1;??
  • ????a1=a2;??
  • ????a2=temp;??
  • ??
  • ????cout<<"change2?執(zhí)行后:"<<endl;??
  • ????cout<<"&a1="<<&a1<<",&a2="<<&a2<<endl;??
  • ????cout<<"*a1="<<*a1<<",*a2="<<*a2<<endl;??
  • ????cout<<"a1="<<a1<<",a2="<<a2<<endl;??
  • }??
  • ??
  • void?change3(int?&a,int?&b)??
  • {??
  • ????cout<<"change3?執(zhí)行前:"<<endl;??
  • ????cout<<"a="<<a<<",b="<<b<<endl;??
  • ????cout<<"&a="<<&a<<",&b="<<&b<<endl;??
  • ??
  • ????int?temp=a;??
  • ????a=b;??
  • ????b=temp;??
  • ??
  • ????cout<<"change3?執(zhí)行后:"<<endl;??
  • ????cout<<"a="<<a<<",b="<<b<<endl;??
  • ????cout<<"&a="<<&a<<",&b="<<&b<<endl;??
  • }??
  • ??
  • void?change4(int?**a,int?**b)??
  • {??
  • ????cout<<"change4?執(zhí)行前:"<<endl;??
  • ????cout<<"&a="<<&a<<",&b="<<&b<<endl;??
  • ????cout<<"a="<<a<<",b="<<b<<endl;??
  • ????cout<<"*a="<<*a<<",*b="<<*b<<endl;??
  • ????cout<<"**a="<<**a<<",**b="<<**b<<endl;??
  • ??????
  • ??
  • ????int?**temp?=?new?int?*;??
  • ????*temp?=?*a;??
  • ????*a?=?*b;??
  • ????*b?=?*temp;??
  • ??
  • ????cout<<endl;??
  • ??
  • ????cout<<"change4?執(zhí)行后:"<<endl;??
  • ????cout<<"&a="<<&a<<",&b="<<&b<<endl;??
  • ????cout<<"a="<<a<<",b="<<b<<endl;??
  • ????cout<<"*a="<<*a<<",*b="<<*b<<endl;??
  • ????cout<<"**a="<<**a<<",**b="<<**b<<endl;??
  • }??
  • ????change0不能實(shí)現(xiàn)目的。簡(jiǎn)單的說(shuō)就是值傳參只是對(duì)實(shí)參的副本進(jìn)行了操作,并不能對(duì)實(shí)參本身進(jìn)行操作。這點(diǎn)會(huì)通過(guò)下面的例子體現(xiàn)出來(lái)。

    ?

    ??? change1能實(shí)現(xiàn)目的,但要注意,這種改變是接改變m和n 的值,而pm和pn的指向未改變(與change4正好相反)。從圖示中能清楚的看出change1中實(shí)現(xiàn)的操作。圖中每個(gè)圓圈或方塊代表一個(gè)變量,上方為自己實(shí)際的內(nèi)存地址,其中的內(nèi)容為他的值。從圖中可以看出,change1執(zhí)行前,生成了兩個(gè)實(shí)參的副本(左側(cè)黃色部分),注意副本的內(nèi)存地址和實(shí)參的不一樣的(不然怎么叫重新生成的),他們的值為各自對(duì)應(yīng)實(shí)參的值。change1實(shí)際上的操作為將變量m和n中的值進(jìn)行互換,而兩個(gè)實(shí)參的副本還是指向原來(lái)的位置(即值不變)。chang1 執(zhí)行后如圖底部所示,指針pm和pn指向的位置不變,但該位置中存儲(chǔ)的內(nèi)容發(fā)生了變化。

    ?

    ??? change2不能實(shí)現(xiàn)交換的目的,從圖中我們可以看書,change2中完成的操作只是將兩個(gè)實(shí)參副本的值互換了,即只把這倆副本指向的位置改變了(當(dāng)然,在change2執(zhí)行結(jié)束后他們將消亡),而我們的目的是想改變pm和pn的指向,或互換m和n的值。change2不能實(shí)現(xiàn)目的的原因和change0的原因相同,都只是改變了副本的值,而真正的實(shí)參沒(méi)進(jìn)行任何操作。所以仍各自保持原來(lái)的值不變。

    ???? change3能實(shí)現(xiàn),他是通過(guò)引用的方式實(shí)現(xiàn)傳遞參數(shù)的。即直接對(duì)傳入?yún)?shù)進(jìn)行操作,而不是對(duì)生成的副本進(jìn)行操作。這樣在change3中對(duì)參數(shù)的任何操作都能直接對(duì)參數(shù)產(chǎn)生影響,如圖所示,當(dāng)change3執(zhí)行完畢后,變量m和n的值已經(jīng)改變了。

    ?? change4是用雙重指針進(jìn)行傳參,他是通過(guò)改變指針pm和pn的指向來(lái)實(shí)現(xiàn)的,而實(shí)際上m和n的值都未改變。但從圖中可以看出,change4執(zhí)行后,ppm和ppn的指向位置未改變,而指向位置的內(nèi)容卻發(fā)生了改變,即執(zhí)行前后ppm始終指向pm,ppn始終指向pn,只不過(guò)是執(zhí)行后pm和pn的指向發(fā)了改變。


    總結(jié):

    利用判斷被調(diào)函數(shù)是對(duì)實(shí)參操作還是對(duì)實(shí)參副本操作來(lái)判斷一個(gè)交換函數(shù)是否真能實(shí)現(xiàn)交換操作;

    利用顯示變量的內(nèi)存地址來(lái)判斷是“實(shí)參”還是“實(shí)參副本”。

    ?

    閱讀原文

    轉(zhuǎn)載于:https://www.cnblogs.com/mayuko/p/4567545.html

    《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的图解C/C++中函数参数的值传递、指针传递与引用传递的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。