關(guān)于函數(shù)傳參問題(指針傳參,值傳參,引用傳參)
形參和實(shí)參
什么是形參(parameter),什么是實(shí)參(argument)
在函數(shù)定義中出現(xiàn)的參數(shù)可以看做是一個(gè)占位符,它沒有數(shù)據(jù),只能等到函數(shù)被調(diào)用時(shí)接收傳遞進(jìn)來的數(shù)據(jù),所以稱為形式參數(shù),簡(jiǎn)稱形參。
給形參傳遞值的變量稱為實(shí)際參數(shù),簡(jiǎn)稱實(shí)參。
形參和實(shí)參關(guān)系
1) 形參變量只有在函數(shù)被調(diào)用時(shí)才會(huì)分配內(nèi)存,調(diào)用結(jié)束后,立刻釋放內(nèi)存,所以形參變量只有在函數(shù)內(nèi)部有效,不能在函數(shù)外部使用。
2) 實(shí)參可以是常量、變量、表達(dá)式、函數(shù)等,無論實(shí)參是何種類型的數(shù)據(jù),在進(jìn)行函數(shù)調(diào)用時(shí),它們都必須有確定的值,以便把這些值傳送給形參,所以應(yīng)該提前用賦值、輸入等辦法使實(shí)參獲得確定值。
3) 實(shí)參和形參在數(shù)量上、類型上、順序上必須嚴(yán)格一致,否則會(huì)發(fā)生“類型不匹配”的錯(cuò)誤。當(dāng)然,如果能夠進(jìn)行自動(dòng)類型轉(zhuǎn)換,或者進(jìn)行了強(qiáng)制類型轉(zhuǎn)換,那么實(shí)參類型也可以不同于形參類型。
實(shí)參為值傳值
代碼:
#include<iostream>
using namespace std;
void swap(int a,int b)
{
cout<<"a address1 = "<<&a<<endl;
cout<<"b address1 = "<<&b<<endl;
int temp = a;
a = b;
b = temp;
}
int main()
{
int a = 10;
int b = 20;
cout<<"a address = "<<&a<<endl;
cout<<"b address = "<<&b<<endl;
cout<<"original "<<"a = "<<a<<" b="<<b<<endl;
swap(a,b);
cout<<"swaped "<<"a = "<<a<<" b="<<b<<endl;
return 0;
}執(zhí)行結(jié)果:

分析結(jié)果:
實(shí)參a,b 和形參a,b的地址是不一樣的,因?yàn)樾螀,b是整型變量,他們?cè)诤瘮?shù)調(diào)用時(shí)分配內(nèi)存,里面只是存放了和實(shí)參對(duì)應(yīng)得整型值,所以改變形參變量a,b的值并沒有改變實(shí)參a,b的值。形參a,b是臨時(shí)變量,當(dāng)函數(shù)運(yùn)行結(jié)束時(shí),他們的生命周期也就結(jié)束了。所以實(shí)參a,b的值并沒有改變。
圖解:

實(shí)參為指針傳值
實(shí)參本身為普通變量
代碼:
#include<iostream>
using namespace std;
void swap(int *a,int *b)
{
cout<<"parameter a address1 = "<<&a<<endl;
cout<<"parameter b address1 = "<<&b<<endl;
cout<<"a value address1 = "<<a<<endl;
cout<<"b value address1 = "<<b<<endl;
int temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int a = 10;
int b = 20;
cout<<"a address = "<<&a<<endl;
cout<<"b address = "<<&b<<endl;
cout<<"original "<<"a = "<<a<<" b="<<b<<endl;
swap(&a,&b);
cout<<"swap "<<"a = "<<a<<" b="<<b<<endl;
return 0;
}
執(zhí)行結(jié)果:

分析結(jié)果:
*p 指的是 指針變量p所指向的地址所存放的內(nèi)容
&p指的是指針本身的地址
p指的是指針?biāo)赶虻膬?nèi)容的地址
實(shí)參傳遞的是實(shí)參a,b的地址,形參a,b為指針類型的變量,也就是對(duì)應(yīng)存放的是實(shí)參a,b變量的地址,函數(shù)內(nèi)交換形參a,b指針?biāo)赶虻刂返膬?nèi)容,也就是交換了實(shí)參a,b地址指向空間的內(nèi)容,所以實(shí)參a,b的內(nèi)容被交換。
圖解:

實(shí)參本身為指針
一級(jí)指針
代碼:
#include<iostream>
using namespace std;
void newPoint(int *p)
{
cout<<"parameter p address = "<<&p<<endl;
p = new int;
*p = 10;
}
int main()
{
int *p = NULL;
cout<<"argument p address = "<<&p<<endl;
newPoint(p);
cout<<"*p = "<<*p<<endl;
delete p;
return 0;
}
~ 執(zhí)行結(jié)果:

分析結(jié)果:
實(shí)參指針p 沒有指向任何類容為空,當(dāng)實(shí)參給形參傳遞值時(shí),傳遞的實(shí)際上是NULL,形參指針p 分配空間,僅僅只是給形參p分配了空間,當(dāng)函數(shù)退出時(shí),實(shí)參指針指向的內(nèi)容還是為空,這時(shí)去訪問實(shí)參p指向的內(nèi)容,因?yàn)橹羔槢]有指向確切地址,就會(huì)產(chǎn)生段錯(cuò)誤,同時(shí)因?yàn)楹瘮?shù)new了空間沒有釋放,還會(huì)造成內(nèi)存泄漏。

二級(jí)指針
代碼:
#include<iostream>
using namespace std;
void newPoint(int **p)
{
cout<<"parameter p address = "<<&p<<endl;
*p = new int;
cout<<"parameter p value = "<<p<<endl;
cout<<"parameter *p value = "<<*p<<endl;
**p = 10;
}
int main()
{
int *p = NULL;
cout<<"argument p address = "<<&p<<endl;
newPoint(&p);
cout<<"argument p value = "<<p<<endl;
cout<<"*p = "<<*p<<endl;
delete p;
return 0;
}
~ 執(zhí)行結(jié)果:

結(jié)果分析:
實(shí)參給形參傳遞的值是實(shí)參本身的地址 0x7ffe7feaa980,形參類型是二級(jí)指針,形參p存放的是一級(jí)指針實(shí)參p的地址,調(diào)用new之后,相當(dāng)于是給實(shí)參指針p分配了空間,實(shí)參指針指向的地址為0x55d013b6d280,給**p賦值,相當(dāng)于是給地址0x55d013b6d280指向的空間賦值,所以當(dāng)函數(shù)返回時(shí),實(shí)參指針指向了確定的地址0x55d013b6d280,并且地址0x55d013b6d280指向的空間值為10;
圖解:

引用傳值
代碼:
#include<iostream>
using namespace std;
void swap(int& a,int& b)
{
cout<<"parameter a address = "<< &a<<endl;
cout<<"parameter b address = "<< &b<<endl;
a = a+b;
b = a-b;
a = a-b;
}
int main()
{
int a = 10;
int b = 20;
cout<<"argument a address = "<<&a<<endl;
cout<<"argument b address = "<<&b<<endl;
cout<<"original value"<<"a = "<<a<<" b ="<<b<<endl;
swap(a,b);
cout<<"swap value"<<"a = "<<a<<" b ="<<b<<endl;
return 0;
}
~ 運(yùn)行結(jié)果:

結(jié)果分析:
引用傳值,函數(shù)形參并沒有給形參分配內(nèi)存,而是和實(shí)參相同的內(nèi)存地址,節(jié)省了開銷,建議能用引用傳值的就用引用。
圖解:

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C++之vector剖析及模擬實(shí)現(xiàn)方式
文章詳解C++ vector實(shí)現(xiàn),涵蓋三個(gè)指針管理動(dòng)態(tài)數(shù)組、容量擴(kuò)容機(jī)制、元素增刪操作及深拷貝原理,強(qiáng)調(diào)迭代器安全性和memcpy對(duì)自定義類型的風(fēng)險(xiǎn),提供使用示例與注意事項(xiàng)2025-09-09
C++實(shí)現(xiàn)LeetCode(135.分糖果問題)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(135.分糖果問題),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
c語言中abs()和fabs()的區(qū)別點(diǎn)整理
在本篇文章里小編給大家分享的是關(guān)于c語言abs()和fabs()的區(qū)別,有需要的朋友們可以參考學(xué)習(xí)下。2020-02-02
C++實(shí)現(xiàn)打地鼠游戲設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)打地鼠游戲設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12
C++使用curl庫進(jìn)行http請(qǐng)求的方法詳解
這篇文章主要為大家詳細(xì)介紹了C++如何使用curl庫進(jìn)行http請(qǐng)求,并且實(shí)現(xiàn)獲取返回的頭信息的時(shí)間,也就是獲取后臺(tái)服務(wù)的當(dāng)前時(shí)間,感興趣的可以了解一下2023-07-07
C++使用grpc實(shí)現(xiàn)回射服務(wù)器
gRPC是由Google開發(fā)的一個(gè)開源的高性能遠(yuǎn)程過程調(diào)用(RPC)框架,用于在分布式系統(tǒng)中實(shí)現(xiàn)跨語言的服務(wù)通信,本文我們就來看看C++如何使用grpc實(shí)現(xiàn)回射服務(wù)器2024-10-10

