前言:
前面我們說的都是無參數無返回值的函數,實際程序中,我們經常使用到帶參數有返回值的函數。
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]會有什麼情況發生?
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; /*返回一個值*/ }和前面的程序有幾點不同:
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目錄裡面。
#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,這樣,我們的主程序中就不需要包含它了,但是這樣做也有副作用,具體有什麼副作用,我們以後接觸到時再介紹。