通過一個實體理解C語言中“函式”“變數”
學習物件:C語言中的‘函式’和‘變數’
學習目標:對‘函式’和‘變數’有一個較為深刻的理解
學習時間:2020/12/18
代碼:
#include<stdio.h>
#include"average.h"
float Max=0,Min=0;
int main()
{
float ave,score[10];
int i;
printf("請輸入10個數\n");
for(i=0;i<sizeof score/sizeof score[0];i++){
scanf("%f",&score[i]);
}
ave=average(score,sizeof score/sizeof score[0]);
printf("max=%6.2f\nmin=%6.2f\naverage=%6.2f\n",Max,Min,ave);
sort(score,sizeof score/sizeof score[0]);
printf("升序排列數為:\n");
for(i=0;i<sizeof score/sizeof score[0];i++){
printf("%.2f\n",score[i]);
}
return 0;
} //file average
float average(float array[],float n)
{ int i;
float sum=array[0],aver;
extern float Max;
extern float Min;
Max=Min=array[0];
for(i=1;i<n;i++){
if(array[i]<Min){
Min=array[i];
}else if(array[i]>Max){
Max=array[i];
}
sum+=array[i];
}
aver=sum/n;
return (aver);
} //average 1
#include"average.h"
void sort(float array[],float n)
{
int i,j,k;
for(i=0;i<n-1;i++){
k=i;
for(j=i+1;j<n;j++){
if(array[j]<array[k]){
k=j;
}
}
swap(&array[k],&array[i]);
}
} //average 2
void swap(float *ex1,float *ex2)
{ float mid;
mid=*ex1;
*ex1=*ex2;
*ex2=mid; //average3
}
float average(float array[],float n);
void sort(float array[],float n);
void swap(float *ex1,float *ex2); //average.h
學習心得
1,用陣列名作函式引數,應該在主調函式和被呼叫函式分別定義陣列,例如在上面的代碼中,array是形引陣列名,score是實引陣列名,分別在其所在的函式中定義,不能只定義一方,
2,實引陣列與形引陣列型別應一致(上面代碼都是float型,便于輸入時附帶小數),如果不一致,結果會報錯,(血的教訓)!
3,在定義array函式時,宣告陣列的大小是沒有任何作用的,因為C語言編譯系統并不檢查形引陣列大小,只是將實引陣列的首元素的地址傳給形引陣列名,因此形引陣列獲得了實引陣列的首元素的地址,而陣列名代表陣列的首元素的地址,因此,形引陣列首元素(array[0])和實引陣列首元素(score[0])具有相同的地址,它們共同占有一儲存單元,score[n]和array[n]指的是同一個單元,score[n]和array[n]具有相同的值,而且,形引陣列中各元素的值發生變化也會使實引陣列元素的值同時發生變化,
這里給大家附張圖,
區域變數和全域變數
1,區域變數:
(a)在一個函式內部定義的變數只在本函式范圍內有效,也就是說只有在本函式內才能參考它們,在此函式外是不能使用這些變數的,
(b)在復合陳述句內定義的變數只在本復合陳述句范圍內有效,只有在本復合陳述句中才能使用它們,


這里就可以很直觀的看都區域變數的有效范圍,另外需要注意的是形式引數也是區域變數,在不同的函式中定義了同名的變數也互不影響,它們在記憶體中占據不同的單元,互不混淆,在復合陳述句中的變數,離開該復合陳述句該變數就無效,系統會把它占用的記憶體單元釋放,
2,全域變數
在函式之外定義的變數稱為外部變數,外部變數是全域變數(也稱全程變數),全域變數可以為本檔案其他函式所共用,它的有效范圍為從定義變數的位置開始到本源檔案結束,
在一個函式中,既可以使用本函式中的區域變數,也可以使用有效的全域變數,例如:
設定全域變數的作用是增加了函式間資料聯系的渠道,由于同一檔案中的所有函式都能參考全域變數的值,因此如果在一個函式中改變全域變數的值,就能影響到其他函式中的全域變數,相當于各個函式之間有直接的通道,通過函式呼叫能夠得到一個以上的值,如果在同一個源檔案中,全域變數與區域變數同名,這時會出現什么情況呢?
#include<stdio.h>
int a=3,b=5;
int main()
{
int max(int a,int b);
int a=8;
printf("max=%d\n",max(a,b));
return 0;
}
int max(int a,int b)
{
return(a>b?a:b) ;
}
大家可以看到的結果是
這就非常阿妹京(amazing)了,故意重復使用a和b作變數名,程式第二行定義了全域變數a和b,并且初始化,第六行再次定義a并且復制8,區域變數的作用范圍為第6~8行,在此范圍內全域變數a被區域變數a屏蔽,相當于全域變數a在此范圍內不存在(即全域變數a在此范圍內不起作用),而全域變數b在此范圍內有效,因此第6行中max(a,b)的實參a應是區域變數,所以max(a,b)相當于max(8,5),它的值是8,
但是全域是有弊端的,因為在執行一個檔案中的操作時,可能會改變該全域變數的值,會影響到另一個檔案中全域變數的值,從而影響該檔案中函式的執行結果,1,全域變數在程式的全部執行程序中都占用儲存單元,而不是僅僅在需要的時候才開辟單元2,它使函式的通用性降低了,因為如果在函式中參考了全域變數,那么執行情況會受到有關的外部變數的影響,如果將一個函式移到另一個檔案中,還要考慮把有關的外部變數及其值一起移過去,但是若該外部變數與其他檔案的變數同名時,就會出現問題,這就降低了程式的可靠性和通用性,在程式設計中,在劃分模塊時要求模塊的“內聚性”強、與其他模塊的“耦合性”弱,即模塊的功能要單一(不要把許多互不相干的功能放到一個模塊中),與其他模塊的相互影響要盡量少,而用全域變數是不符合這個原則的,一般要求把C程式中的函式做成一個相對的封閉體,除了可以通過“實參—形參”的渠道與外界發生聯系外,沒有其他渠道,這樣的程式移植性好,可讀性強3,使用全域變數過多,會降低程式的清晰性,人們往往難以清楚地判斷出每個瞬時各個外部變數的值,由于在各個函式執行時都可能改變外部變數的值,程式容易出錯,因此,要限制使用全域變數,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/237114.html
標籤:其他
