函式引數的傳遞和值返回

2022-12-24 19:00:03 字數 3486 閱讀 2280

前面我們說的都是無引數無返回值的函式,實際程式中,我們經常使用到帶引數有返回值的函式。

一、函式引數傳遞

1.形式引數和實際引數

函式的呼叫值把一些表示式作為引數傳遞給函式。函式定義中的引數是形式引數,函式的呼叫者提供給函式的引數叫實際引數。在函式呼叫之前,實際引數的值將被拷貝到這些形式引數中。

2.引數傳遞

先看乙個例子:

void a(int); /*注意函式宣告的形式*/

main()

void a(int num_back) /*注意定義形式*/

在主函式中,先定義乙個變數,然後輸入乙個值,在a()這個函式中輸出。當程式執行a(num);這一步時,把num的值賦值給num_back,在執行程式過程中,把實際引數的值傳給形式引數,這就是函式引數的傳遞。

形參和實參可能不只乙個,如果多於乙個時,函式宣告、呼叫、定義的形式都要一一對應,不僅個數要對應,引數的資料型別也要對應。

void a(int,float);

main()

void a(int num1_back,float num2_back)

上面的例子中,函式有兩個引數,乙個是整型,乙個是浮點型,那麼在宣告、呼叫、定義的時候,不僅個數要一樣,型別也要對應。如果不對應,有可能使的編譯錯誤,即使沒錯誤,也有可能讓資料傳遞過程**現錯誤。

再看乙個例子:

void a(int);

main()

void a(int num)

看上面的例子,形式引數和實際引數的識別符號都是num,程式把實際引數num的值傳遞給形式引數num。有些人可能就不明白了,既然兩個都是num,為什麼還要傳遞呢?乾脆這樣不就行了嗎:

void a();

main()

void a()

其實不然,這就要涉及到識別符號作用域的問題。作用域的意思就是說,哪些變數在哪些範圍內有效。乙個識別符號在乙個語句塊中宣告,那麼這個識別符號僅在當前和更低的語句塊中可見,在函式外部的其實地方不可見,其他地方同名的識別符號不受影響,後面我們會系統講解作用域的問題。

在這兒你就要知道兩個同名的變數在不同的函式中是互不干擾的。

前面將的都是變數與變數之間的值傳遞,其實函式也可以傳遞陣列之間的值。看下面的例子:

void a(int );

main()

void a(int array)

這就是陣列之間的值傳遞。注意他們的宣告和定義形式,和變數引數傳遞有什麼區別?有了後面的就表明傳遞的是乙個陣列。

其中在定義的時候,也可以寫成void a(int array[5]);想想,如果我們寫成了int array[4]會有什麼情況發生?

目前我們只學了陣列和變數,以後還會知道指標、結構,到那是,函式也可以傳遞它們之間的值。

二、函式值的返回

其實我們也可以把函式當作乙個變數來看,既然是變數,那一定也可以有型別。還舉最前面的例子,現在要求在main()函式裡輸入乙個整數作為正方形的邊長,在子函式裡求正方形的面積,然後再在主函式裡輸出這個面積。

我們前面的程式都是在子函式裡輸出的,現在要求在主函式裡輸出,這就需要把算好的值返回回來。先看例子:

int a(int); /*宣告函式*/

main()

int a(int num)

和前面的程式有幾點不同:

(1).宣告函式型別時,不是void,而是int。這是由於最後要求的面積是整型的,所以宣告函式的返回值型別是整型。

(2).return語句它的意思就是返回乙個值。在c語言中,return一定是在函式的最後一行。

(3).呼叫函式的時候,由於函式有乙個返回值,所以必須要用變數接受這個返回值(不是絕對的),如果我們不用乙個變數接受這個值,函式還照樣返回,但是返回的這個值沒有使用。

上面的例子執行過程是這樣的,先把實參的值傳遞給形參,然後在子函式裡計算面積得到area_back,然後返回這個面積到主函式,也就是把area_back賦值給area,最後輸出。

前面說了,返回值有時不一定非要用乙個變數來接受,我們可以把上面的程式簡化為:

int a(int);

main()

int a(int num)

這樣函式返回的值就可以直接放到輸出緩衝區直接輸出了。

還可以再簡化為:

int a(int);

main()

int a(int num)

對於函式而言,乙個函式只能返回乙個值,如果想返回一組數值,就要使用陣列或者結構或者指標。其實對於這些,還是返回乙個值,只是這個值是乙個位址而已。但是對於陣列的返回有和變數不同,因為陣列和位址是聯絡在一起的。

看乙個例子:

void a(int );

main()

,i;a(array);

for(i=0;i<5;i++) printf(%d,array[i]);

}void a(int array)

看看這個程式,好象函式沒有返回值,但是函式的功能的確實現了,在主函式當中輸出的值的確都各加了1上來。這就是因為陣列和變數不同的緣故,在後面講指標的時候再詳細說明。

下面看乙個實際例子,加深對函式的理解:

用函式實現,判斷乙個整數是不是素數?在主函式裡輸入輸出,子函式裡判斷。

#include

int judge(int);

main()

judge(int num)

return flag;

}可以看出,函式的功能就是為了讓程式看起來有條理,乙個函式實現乙個特定的功能。如果我們還和以前那樣,把所有**都放在main()函式,好象程式就顯的臃腫了。而且函式有乙個顯著的好處就是很方便的使用。

這裡面的judge()函式判斷乙個數是不是素數,如果我們以後還有判斷某個數是不是素數,就可以直接使用這個函式了。我們這樣,把下面的**:

judge(int num)

return flag;

}儲存為檔案,放到include目錄裡面。

以後就可以直接使用這個函式了,就好象直接使用abs(),sqrt()這些函式一樣方便。

#include /*必須要有它*/

#include

main()

看上面的例子,我們在程式中直接使用了函式judge(),這就是我們自己編寫的第乙個所謂的庫函式。但是程式的第一行要包含檔案,這是因為在裡面使用了sqrt()函式,所以為了方便,我們可以把放到裡面,也就是在檔案的第一行加上include 這樣,我們的主程式中就不需要包含它了,但是這樣做也有***,具體有什麼***,我們以後接觸到時再介紹。

我們實際用到的一些程式,也許**有很長,上千行,甚至上萬行,這些**不可能放在乙個*.c檔案中,所以我們經常把一些功能做成*.h,*c的檔案形式,然後在主程式中包含這些檔案,這樣就把乙個大程式分割成幾個小塊,不僅瀏覽方便,對以後的修改也有很多好處。

我們在平時就應該有這樣的好習慣,把一些經常使用的功能做成庫函式的形式儲存下來,也許剛開始你會覺得很煩瑣,可到了後來,也許幾年過去了,你會發現,乙個好幾千行上萬行的程式,有一大半的功能你都有,直接呼叫就可,這會大大縮短你的程式開發週期的。就好象這裡的判斷素數一樣,如果以後還需要判斷乙個數是不是素數,就沒必要再寫那些**了,直接呼叫judge()函式就可。

返回指定平均值和標準偏差的正態分佈函式

返回指定平均值和標準偏差的正態分佈函式。此函式在統計方面應用範圍廣泛 包括假設檢驗 語法 normdist x,mean,standard dev,cumulative x需要計算其分布的數值。mean分布的算術平均值。standard dev分布的標準偏差。cumulative邏輯值,決定函式的形...

關於多元函式的極值和最值計算

一 可微函式的無條件極值 如果在區域上存在二階連續偏導數,我們可以用下面的方法求出極值。首先,通過解方程得到駐點。其次,對每個駐點求出二階偏導數 最後利用課本定理7.8進行判斷。函式在此點取極小值 函式在此點取極大值 函式在此點不取極值 不能確定。二 如何求多元函式的最值 如果函式在有界閉域上連續,...

《函式的最大值和最小值與導數》教學設計

課本教材內容分析 本節教材知識間的前後聯絡,以及在課堂教學中的地位與作用 導數 導函式的簡稱 是乙個特殊函式,它的引出和定義始終貫穿著函式思想。新課程增加了導數的內容,隨著課改的不斷深入,導數知識考查的要求逐漸加強,而且導數已經由前幾年只是在解決問題中的輔助地位上公升為分析和解決問題時的不可缺少的工...