1. 程式人生 > >c語言的引數

c語言的引數

函式的引數—實參|形參

在函式定義中出現的引數可以看做是一個佔位符,它沒有資料,只能等到函式被呼叫時接收傳遞進來的資料,所以稱為形式引數,簡稱形參

函式被呼叫時給出的引數包含了實實在在的資料,會被函式內部的程式碼使用,所以稱為實際引數,簡稱實參

形參和實參的功能是傳遞資料,發生函式呼叫時,實參的值會傳遞給形參。

形參和實參有以下幾個特點:
1) 形參變數只有在函式被呼叫時才會分配記憶體,呼叫結束後,立刻釋放記憶體,所以形參變數只有在函式內部有效,不能在函式外部使用。

2) 實參可以是常量、變數、表示式、函式等,無論實參是何種型別的資料,在進行函式呼叫時,它們都必須有確定的值,以便把這些值傳送給形參,所以應該提前用賦值、輸入等辦法使實參獲得確定值。

3) 實參和形參在數量上、型別上、順序上必須嚴格一致,否則會發生“型別不匹配”的錯誤。當然,如果能夠進行自動型別轉換,或者進行了強制型別轉換,那麼實參型別也可以不同於形參型別。

4) 函式呼叫中發生的資料傳遞是單向的,只能把實參的值傳遞給形參,而不能把形參的值反向地傳遞給實參;換句話說,一旦完成資料的傳遞,實參和形參就再也沒有瓜葛了,所以,在函式呼叫過程中,形參的值發生改變並不會影響實參。

 1 #include <stdio.h>
 2 
 3 //計算從1加到n的值
 4 int sum(int n){
 5     int i;
 6     for(i=n-1; i>=1; i--){
 7         n+=i;
 8     }
 9     printf("The inner n = %d\n",n);
10     return n;
11 }
12 
13 int main(){
14     int m, total;
15     printf("Input a number: ");
16     scanf("%d", &m);
17 total = sum(m); 18 printf("The outer m = %d \n", m); 19 printf("1+2+3+...+%d+%d = %d\n", m-1, m, total); 20 return 0; 21 }

執行結果:
Input a number: 100↙
The inner n = 5050
The outer m = 100
1+2+3+...+99+100 = 5050

通過 scanf 輸入 m 的值,作為實參,在呼叫 sum() 時傳送給形參 n。

從執行情況看,輸入 m 值為100,即實參 m 的值為100,把這個值傳給函式 sum 時,形參 n 的初始值也為100,在函式執行過程中,形參 n 的值變為 5050。函式執行結束後,輸出實參 m 的值仍為100,可見實參的值不隨形參的變化而變化。

 

摘自http://c.biancheng.net/cpp/html/57.html

 

區域性變數

定義在函式內部的變數稱為區域性變數(Local Variable),它的作用域僅限於函式內部, 離開該函式後就是無效的,再使用就會報錯。

  • 在 main 函式中定義的變數也是區域性變數,只能在 main 函式中使用;同時,main 函式中也不能使用其它函式中定義的變數。main 函式也是一個函式,與其它函式地位平等。
  • 形參變數、在函式體內定義的變數都是區域性變數。實參給形參傳值的過程也就是給區域性變數賦值的過程。
  • 可以在不同的函式中使用相同的變數名,它們表示不同的資料,分配不同的記憶體,互不干擾,也不會發生混淆。
  • 在語句塊中也可定義變數,它的作用域只限於當前語句塊。

 

1 int f1(int a){
2     int b,c;  //a,b,c僅在函式f1()內有效
3     return a+b+c;
4 }
5 int main(){
6     int m,n;  //m,n僅在函式main()內有效
7     return 0;
8 }

 

全域性變數

在所有函式外部定義的變數稱為全域性變數(Global Variable),它的作用域預設是整個程式,也就是所有的原始檔,包括 .c 和 .h 檔案。

 1 int a, b;  //全域性變數
 2 void func1(){
 3     //TODO:
 4 }
 5 
 6 float x,y;  //全域性變數
 7 int func2(){
 8     //TODO:
 9 }
10 
11 int main(){
12     //TODO:
13     return 0;
14 }

a、b、x、y 都是在函式外部定義的全域性變數。C語言程式碼是從前往後依次執行的,由於 x、y 定義在函式 func1() 之後,所以在 func1() 內無效;而 a、b 定義在源程式的開頭,所以在 func1()、func2() 和 main() 內都有效。

區域性變數和全域性變數的綜合示例

 1 #include <stdio.h>
 2 
 3 int n = 10;  //全域性變數
 4 
 5 void func1(){
 6     int n = 20;  //區域性變數
 7     printf("func1 n: %d\n", n);
 8 }
 9 
10 void func2(int n){
11     printf("func2 n: %d\n", n);
12 }
13 
14 void func3(){
15     printf("func3 n: %d\n", n);
16 }
17 
18 int main(){
19     int n = 30;  //區域性變數
20     func1();
21     func2(n);
22     func3();
23     //程式碼塊由{}包圍
24     {
25         int n = 40;  //區域性變數
26         printf("block n: %d\n", n);
27     }
28     printf("main n: %d\n", n);
29 
30     return 0;
31 }

執行結果:
func1 n: 20
func2 n: 30
func3 n: 10
block n: 40
main n: 30

程式碼中雖然定義了多個同名變數 n,但它們的作用域不同,在記憶體中的位置(地址)也不同,所以是相互獨立的變數,互不影響,不會產生重複定義(Redefinition)錯誤。

1) 對於 func1(),輸出結果為 20,顯然使用的是函式內部的 n,而不是外部的 n;func2() 也是相同的情況。

當全域性變數和區域性變數同名時,在區域性範圍內全域性變數被“遮蔽”,不再起作用。或者說,變數的使用遵循就近原則,如果在當前作用域中存在同名變數,就不會向更大的作用域中去尋找變數。

2) func3() 輸出 10,使用的是全域性變數,因為在 func3() 函式中不存在區域性變數 n,所以編譯器只能到函式外部,也就是全域性作用域中去尋找變數 n。

3) 由{ }包圍的程式碼塊也擁有獨立的作用域,printf() 使用它自己內部的變數 n,輸出 40。

3) C語言規定,只能從小的作用域向大的作用域中去尋找變數,而不能反過來,使用更小的作用域中的變數。對於 main() 函式,即使程式碼塊中的 n 離輸出語句更近,但它仍然會使用 main() 函式開頭定義的 n,所以輸出結果是 30。