關于函數(shù)傳參問題(指針傳參,值傳參,引用傳參)
形參和實參
什么是形參(parameter),什么是實參(argument)
在函數(shù)定義中出現(xiàn)的參數(shù)可以看做是一個占位符,它沒有數(shù)據(jù),只能等到函數(shù)被調用時接收傳遞進來的數(shù)據(jù),所以稱為形式參數(shù),簡稱形參。
給形參傳遞值的變量稱為實際參數(shù),簡稱實參。
形參和實參關系
1) 形參變量只有在函數(shù)被調用時才會分配內存,調用結束后,立刻釋放內存,所以形參變量只有在函數(shù)內部有效,不能在函數(shù)外部使用。
2) 實參可以是常量、變量、表達式、函數(shù)等,無論實參是何種類型的數(shù)據(jù),在進行函數(shù)調用時,它們都必須有確定的值,以便把這些值傳送給形參,所以應該提前用賦值、輸入等辦法使實參獲得確定值。
3) 實參和形參在數(shù)量上、類型上、順序上必須嚴格一致,否則會發(fā)生“類型不匹配”的錯誤。當然,如果能夠進行自動類型轉換,或者進行了強制類型轉換,那么實參類型也可以不同于形參類型。
實參為值傳值
代碼:
#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í)行結果:
分析結果:
實參a,b 和形參a,b的地址是不一樣的,因為形參a,b是整型變量,他們在函數(shù)調用時分配內存,里面只是存放了和實參對應得整型值,所以改變形參變量a,b的值并沒有改變實參a,b的值。形參a,b是臨時變量,當函數(shù)運行結束時,他們的生命周期也就結束了。所以實參a,b的值并沒有改變。
圖解:
實參為指針傳值
實參本身為普通變量
代碼:
#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í)行結果:
分析結果:
*p 指的是 指針變量p所指向的地址所存放的內容
&p指的是指針本身的地址
p指的是指針所指向的內容的地址
實參傳遞的是實參a,b的地址,形參a,b為指針類型的變量,也就是對應存放的是實參a,b變量的地址,函數(shù)內交換形參a,b指針所指向地址的內容,也就是交換了實參a,b地址指向空間的內容,所以實參a,b的內容被交換。
圖解:
實參本身為指針
一級指針
代碼:
#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í)行結果:
分析結果:
實參指針p 沒有指向任何類容為空,當實參給形參傳遞值時,傳遞的實際上是NULL,形參指針p 分配空間,僅僅只是給形參p分配了空間,當函數(shù)退出時,實參指針指向的內容還是為空,這時去訪問實參p指向的內容,因為指針沒有指向確切地址,就會產(chǎn)生段錯誤,同時因為函數(shù)new了空間沒有釋放,還會造成內存泄漏。
二級指針
代碼:
#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í)行結果:
結果分析:
實參給形參傳遞的值是實參本身的地址 0x7ffe7feaa980,形參類型是二級指針,形參p存放的是一級指針實參p的地址,調用new之后,相當于是給實參指針p分配了空間,實參指針指向的地址為0x55d013b6d280,給**p賦值,相當于是給地址0x55d013b6d280指向的空間賦值,所以當函數(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; } ~
運行結果:
結果分析:
引用傳值,函數(shù)形參并沒有給形參分配內存,而是和實參相同的內存地址,節(jié)省了開銷,建議能用引用傳值的就用引用。
圖解:
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
C++實現(xiàn)LeetCode(50.求x的n次方)
這篇文章主要介紹了C++實現(xiàn)LeetCode(50.求x的n次方),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下2021-07-07