函數的參數分為兩種,分別是形式參數與實際參數。
①形式參數:
在定義函數時函數名后面括號中的變量名稱稱為形式參數(簡稱形參),即形參出現在函數定義中。形參變量只有在被調用時才會為其分配內訓單元,在調用結束時,即刻釋放所分配的內存單元。因此,形參只在函數內部有效,只有當函數被調用時,系統才為形參分配存儲單元,並完成實參與形參的數據傳遞。在函數未被調用時,函數的形參並不占用實際的存儲單元,也沒有實際值。
②實際參數:
主調函數中調用一個函數時,函數名后面括號中的參數稱為實際參數(簡稱實參),即實參出現在主調函數中。
實參可以是常量,變量,表達式,函數等,無論實參是何種類型的量,在進行函數調用時,它們都必須具有確定的值,以便把這些值傳遞給形參。因此應預先用賦值,輸入等辦法使實參獲得確定值。
說明:在被定義的函數中,必須指定形參的類型。實參與形參的類型應相同或賦值兼容。實參和形參在數量上,類型上,順序上應該嚴格一致,否則會發生類型不匹配的錯誤。
C語言中函數的值傳遞有兩種,一種是傳遞數值(即傳遞基本類型的數據,結構體數據),另一種是傳遞地址(即傳遞存儲單元的地址)。
1.傳數值:
調用函數時,給形參分配存儲單元,並將實參對應的值傳遞給形參,形參的值的改變並不會影響實參。調用結束后,形參所占內存單元被釋放,實參仍保持原值不變。該方法只能是實參向形參傳遞數據,即該方法是單向傳遞。
傳數值,實參的值時基本數據類型,結構體類型數據,實參可以是常量,變量或表示式,其值類型是整形,實型,字符型,數組元素等數據而不能是數組名或指針等數據。當函數調用時,先為形參分配獨立的存儲單元,同時將實參的值賦值給形參變量。因此,在函數體執行中,形參函數的任何改變都不會改變實參的值。
數值傳遞中,形參的值改變不會影響實參實例:
#include <stdio.h> int main() { int n,m; void swap(int,int); //聲明函數 printf("please input two numbers:"); scanf("%d%d",&n,&m); printf("n=%d,m=%d\n",n,m); //第一次輸出 swap(n,m); //第二次輸出 printf("n=%d,m=%d\n",n,m); //第三輸出 } void swap(int x,int y) //定義函數 { int i; i=x; x=y; y=i; printf("x=%d,y=%d\n",x,y); }
運行結果:
please input two numbers:5 7
n=5,m=7
x=7,y=5
n=5,m=7
由此可見,調用swap函數只交換了兩個形參的值,而實參的值並沒有發生變換。
2.傳地址:
在實際應用中,往往需要將形參的返回值給實參,所以需要雙向傳遞,這時可以使用傳地址方式。當用表示地址的數組名或者指針變量作為函數參數進行參數傳遞時就不是傳輸至,實際上傳遞的是地址,即把實參所存放的地址賦予形參。由於形參在調用所得到的是實參所值的地址,因而形參和實參將占用同一片內存空間,即兩者指向同一個對象,在函數體重可以通過地址,訪問相應的變量,而達到改變主調函數中的變量值。因此在被調用函數中對形參所做的操作都會影響到實參。
采用傳地址方式時,函數定義中的形參可以是數組作為形參或指針變量作為形參。數組是內存中的一塊存儲區域,數組名表示這塊存儲區域的首地址,通過首地址可以實現對數組中各元素的訪問。數組作為函數的參數,其本質是把數組的首地址傳給形參,使形參數組與實參數組成為同一個數組,使用同一塊存儲區域,即形參數組的存儲區域就是是參數組的存儲區域,因此在被調用函數中對形參數組的訪問,就是對主調函數中數組的訪問,而達到引用主調函數中數組元素。
下面來看實例:
//將數組中的n個整數,按值從小到大排序。 #include <stdio.h> int main() { int b[10]={1,6,2,3,10,23,11,0,21,8}; int i; printf("排序前:\n"); for(i=0;i<10;i++) printf("%d\t",b[i]); printf("\n"); void sort(int a[],int n); //調用選擇排序法函數 sort(b,10); printf("排序后:\n"); for(i=0;i<10;i++) printf("%d\t",b[i]); } //選擇排序法 void sort(int a[],int n) { int i,j,k,t; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(a[k]>a[j]) k=j; t=a[k];a[k]=a[i];a[i]=t; } } //冒泡排序法 void sort1(int a[],int n) { int i,j; int temp; //中間變量 for(i=0;i<n;i++) for(j=0;j<n-i-1;j++) if(a[j]>a[j+1]) { temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; } }
選擇排序法比冒泡排序法的程序要更好一點,但是也更不易理解一點。
基礎好一點的可以用選擇排序法,基礎差一點可以選擇用冒泡排序法。