python所有函數講解「c語言返回數組的函數」

函數參數的傳遞和值返回

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

一、函數參數傳遞

1.形式參數和實際參數

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

2.參數傳遞

先看一個例子:

void a(int); /*注意函數聲明的形式*/

main()

{

int num;

scanf(%d,&num);

a(num); /*注意調用形式*/

}

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

{

printf(%d\n,num_back);

}

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

形參和實參可能不只一個,如果多於一個時,函數聲明、調用、定義的形式都要一一對應,不僅個數要對應,參數的數據類型也要對應。

void a(int,float);

main()

{

int num1;

float num2;

scanf(%d,&num1);

scanf(%f,&num2);

a(num1,num2);

}

void a(int num1_back,float num2_back)

{

printf(%d,%f\n,num1_back,num2_back);

}

上面的例子中,函數有兩個參數,一個是整型,一個是浮點型,那麼在聲明、調用、定義的時候,不僅個數要一樣,類型也要對應。如果不對應,有可能使得編譯錯誤,即使沒錯誤,也有可能讓數據傳遞過程中出現錯誤。

再看一個例子:

void a(int);

main()

{

int num;

scanf(%d,&num);

a(num);

}

void a(int num)

{

printf(%d\n,num);

}

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

void a();

main()

{

int num;

scanf(%d,&num);

a();

}

void a()

{

printf(%d\n,num);

}

其實不然,這就要涉及到標識符作用域的問題。作用域的意思就是說,哪些變量在哪些範圍內有效。一個標識符在一個語句塊中聲明,那麼這個標識符僅在當前和更低的語句塊中可見,在函數外部的其實地方不可見,其他地方同名的標識符不受影響,後面我們會系統講解作用域的問題。在這兒你就要知道兩個同名的變量在不同的函數中是互不干擾的。

前面講的都是變量與變量之間的值傳遞,其實函數也可以傳遞數組之間的值。看下面的例子:

void a(int []);

main()

{

int array[5],i;

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

a(array);

}

void a(int array[])

{

int i;

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

printf(\n);

}

這就是數組之間的值傳遞。注意他們的聲明和定義形式,和變量參數傳遞有什麼區別?有了後面的[]就表明傳遞的是一個數組。其中在定義的時候,也可以寫成void a(int array[5]);想想,如果我們寫成了int array[4]會有什麼情況發生?

目前我們只學了數組和變量,以後還會知道指針、結構,到那時,函數也可以傳遞它們之間的值。

二、函數值的返回

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

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

int a(int); /*聲明函數*/

main()

{

int num,area;

scanf(%d,&num);

area=a(num); /*調用時的形式*/

printf(%d,area);

}

int a(int num)

{

int area_back;

area_back=num*num;

return area_back; /*返回一個值*/

}

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

(1).聲明函數類型時,不是void,而是int。這是由於最後要求的面積是整型的,所以聲明函數的返回值類型是整型。

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

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

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

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

int a(int);

main()

{

int num;

scanf(%d,&num);

printf(%d,a(num)); /*函數調用放在這兒*/

}

int a(int num)

{

int area_back;

area_back=num*num;

return area_back;

}

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

還可以再簡化為:

int a(int);

main()

{

int num;

scanf(%d,&num);

printf(%d,a(num));

}

int a(int num)

{

return num*num; /*直接在這兒返回*/

}

對於函數而言,一個函數只能返回一個值,如果想返回一組數值,就要使用數組或者結構或者指針。其實對於這些,還是返回一個值,只是這個值是一個地址而已。但是對於數組的返回有和變量不同,因為數組和地址是聯繫在一起的。看一個例子:

void a(int []);

main()

{

int array[5]={1,2,3,4,5},i;

a(array);

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

}

void a(int array[])

{

int i;

for(i=0;i<5;i++) array[i]++;

}

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

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

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

#include math.h

int judge(int);

main()

{

int num,result;

scanf(%d,&num);

result=judge(num);

if(result==1) printf(yes\n);

else printf(no\n);

}

judge(int num)

{

int i,flag=1;

for(i=2;i<=sqrt(num);i++)

if(num%i==0)

{

flag=0;

break;

}

return flag;

}

可以看出,函數的功能就是為了讓程序看起來有條理,一個函數實現一個特定的功能。如果我們還和以前那樣,把所有代碼都放在main()函數,好象程序就顯得臃腫了。而且函數有一個顯著的好處就是很方便的使用。這裏面的judge()函數判斷一個數是不是素數,如果我們以後還有判斷某個數是不是素數,就可以直接使用這個函數了。我們這樣,把下面的代碼:

judge(int num)

{

int i,flag=1;

for(i=2;i<=sqrt(num);i++)

if(num%i==0)

{

flag=0;

break;

}

return flag;

}

保存為judge.h文件,放到include目錄裏面。

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

#include math.h /*必須要有它*/

#include judge.h

main()

{

int num,result;

scanf(%d,&num);

result=judge(num);

if(result==1) printf(yes\n);

else printf(no\n);

}

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

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

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

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/268696.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-16 13:11
下一篇 2024-12-16 13:11

相關推薦

發表回復

登錄後才能評論