C 函式的形參

2021-08-20 13:25:28 字數 3545 閱讀 5577

這些天又在複習c++,溫故知新,每次看書都會發現一些之前被自己忽視掉的知識點,所以,學習是不能止步的!

作為一種程式語言,c++最重要的兩個部分就是函式和變數,這兩者之間進行溝通便是通過引數傳遞,而引數傳遞有很多需要注意的細節,今天就來講講引數傳遞的問題。

總的來說,引數傳遞的過程,就是初始化函式形參的過程。

按值傳遞是最直接也是最容易理解的引數傳遞方式,其形式如下;

void fun(int x,int y)    //定義;

fun(a,b);                           //呼叫

當進行呼叫的時候,將引數的值通過拷貝賦值給形參,形參的值在函式體內進行各種計算時,並不影響函式外實參的值,形參值的改變與實參無關;

傳值過程是這樣的;

int y = b; int x = a;
下面這個例子就說明了這點;

#includeusing namespace std;

void swap(int, int);

void main()

void swap(int x, int y)

//定義;

fun(&a,&b);                           //呼叫;

在傳參過程中,形參初始化的操作如下;

int *y = &b; int *x= &a;
這時候重新定義swap()函式,會發現a,b的值被修改了,因為,函式通過指標修改了指標指向的物件的值,這就修改了a,b本身。

眾所周知,對於引用的操作就是對物件本身的操作,引用是被引用物件本身的乙個「別名」,按引用傳遞引數與引用類似,形參成為了實參的乙個「別名」,它的形式如下;

void fun(int &x,int &y)    //定義;

fun(a,b);                           //呼叫;

形參初始化的操作如下;

int &y = b; int &x= a;
可以想見,當按引用傳值時,在函式中修改形參的值時,實參的值也被修改了,事實也正是如此。

避免進行拷貝操作

雖然在我們的例子中都用的是簡單的int型別,但是在實際使用中,常常需要傳遞很大的容器物件,或者是大的類型別物件,這些時候需要呼叫拷貝建構函式進行傳參,效率低下,通過引用可以很好的避免這一點,大大地節約計算時間和計算資源。

用於返回資訊

我們知道,乙個函式一次只能返回乙個值,當需要通過函式知道多個變數的資訊是,僅僅有返回值是不夠的,引用形參為我們提供了很好的渠道,通過引用可以獲得函式計算後的各個值,甚至不需要接收函式的返回值。

與普通變數一樣,陣列也可以作為函式的形參。但是在《【c++】細說c++中的陣列之「靜態」陣列》中我們提到過,陣列是不允許被拷貝的,因此我們不能以傳值的形式使用陣列形參,所以改換成傳位址的方式向函式傳遞陣列實參的資訊。

當且僅當用於函式頭或者函式原型時,int *arr與int arr是含義相同的,他們都意味著arr是乙個指標。所以下面三者是等價的;

int* multi(int a,int m);

int* multi(int *a,int m);

int* multi(int a[10],int m);

將陣列作為形參時,其實是將陣列首元素的位址,包含元素的種類,以及元素的數目提交給了函式,有了這些資訊後,函式就可以使用陣列的資訊了。但是,也有一些問題需要注意,當我們有乙個陣列時,可以獲得陣列的大小(利用sizeof()函式),但是當它轉化成指標後,我們沒法獲得它的大小,所以常常顯示地向函式傳遞陣列的大小;

變數可以定義成陣列的引用,形參也同樣可以,   

int* multi(int (&a)[10],int m);

//注:&a兩端的括號不能少,因為的優先順序更高;c++也不允許引用的陣列。其次,必須給定陣列的大小,這在一定程度上限制了函式的使用。

與陣列一樣,多維陣列也可以作為形參傳遞給函式,與一維陣列一樣,傳遞的也是陣列首元素的位址。因為處理的是陣列的陣列,所以首元素本身是乙個陣列,指標指向的是乙個陣列,因此第二維的陣列的大小不能被省略。

int* multi(int (*a)[10],int m);

//注:*a兩端的括號不能掉,因為的優先順序更高如果失去了括號,那麼int *a[10]表示的是包含十個int型別指標的陣列。而前者表示a是乙個指標,指向含有十個元素的陣列。

很多情況下都要用到預設值的形參,例如opencv中的很多函式都使用了預設形參,這樣使得函式更加靈活好用。

當函式提供了形參的預設值,形參就不是必須要從實參獲得值,那麼在函式呼叫時,也不是必須提供與形引數一致的實參。

形參與實參匹配是從左到右的,第乙個形參與第乙個實參匹配,第二個形參與第二個實參匹配。因此,指定預設值的形參必須放在形參列表的最右側,或者說,在帶預設值的形參的右邊,不允許出現無預設值的形參;

int add(int x = 10, int y = 20)

add();

add(a);

add(a, b);

float f1(float a,float b=1,float c,float d=0); //錯誤

float f1(float a,float b,float c=1,float d=0); //正確

這裡也只是簡單的列舉了一下c++中形參和引數傳遞的內容,還有很多複雜的內容需要在專案實踐中去了解,但是萬變不離其宗,這些東西是我們必須掌握的。

已完。。

C 帶預設形參的函式

先上 int sub int x 8,int y 3 void main 注意事項 1 c 呼叫函式時,引數是自由到左入棧的。因此,預設形參必須從右向左連續定義,並且在乙個預設形參的右邊不能有非預設的形參。int f int a,float b 5.0,char c int d 10 正確 int ...

函式指標形參

一 在介紹指標形參之前,先簡要說明下兩個運算子 和 1 取址運算子 用來取得其運算元的位址。取址運算子的運算元必須是在記憶體中可定址到。換句話說,該運算子只能用作函式或物件 例如左值 而不可以用於位欄位,以及那些未被儲存型別修飾符register宣告的內容。float x,ptr ptr x 合法 ...

函式形參 內聯函式

1.形參帶預設值的函式 1.給預設值,需要從右向左給,壓棧的時候從右向左壓。int sum int a 10,int b 這樣是錯誤的2.給預設值呼叫效率高 因為呼叫時給值,h彙編會直接壓棧,如果是給變數值,還需要多一條move指令,需要從記憶體中取值到暫存器,再壓棧。3.定義可以給形參預設值,宣告...