回顧:
在定義函數時函數括號中的變量名成為形式參數,簡稱形參或虛擬參數;在主調函數中調用一個函數時,該函數括號中的參數名稱為實際參數,簡稱實參,實參可以是常量、變量或表達式。
注意:
1、C語言中實參和形參之間的額數據傳遞是單向的“值傳遞”,單向傳遞,只能由實參傳給形參,反之不能。
2、被調用函數的形參只有函數被調用時才會臨時分配存儲單元,一旦調用結束占用的內存便會被釋放。
3、”按值傳遞“中包括值傳遞(實實在在的值啊!)和指針傳遞(指針傳遞參數本質上是值傳遞的方式,它所傳遞的是一個地址值),傳遞的都是實參的一個拷貝。
一、按值傳遞
主調函數向調用函數傳遞參數實際上只是將實參的拷貝(即臨時副本)傳遞給了被調用函數,並不是實參本身,這樣被調函數不能直接修改主調函數中變量的值,而只能修改其私有的臨時副本的值。
1、例子1:值傳遞(實實在在的值啊)
1 #include <stdio.h> 2 int main() 3 { 4 int a=2,b=3; 5 void swap(int x,int y); 6 printf("before:%d,%d\n",a,b); 7 swap(a,b); 8 printf("later:%d,%d\n",a,b); 9 return 0; 10 } 11 12 void swap(int x,int y) 13 { 14 int tmp; 15 tmp=x; 16 x=y; 17 y=tmp; 18 }
運行結果:
下面的例子體現了不論傳遞的是值還是指針(指針也是一個值),傳遞給被調用函數的都是實參的一個拷貝,直接對拷貝進行操作不會影響實參
1 #include <stdio.h> 2 int main() 3 { 4 int a = 2, b = 3; 5 printf("before:%d,%d\n", a, b); 6 printf("---------------------------\n"); 7 printf("a所在的地址為:%x\n", &a); 8 printf("b所在的地址為:%x\n", &b); 9 printf("---------------------------\n"); 10 void swap(int* x, int* y); 11 swap(&a, &b); 12 printf("later:%d,%d\n", a, b); 13 return 0; 14 15 } 16 17 void swap(int* x, int* y) 18 { 19 printf("x所在的地址為:%x\n", &x); 20 printf("y所在的地址為:%x\n", &y); 21 printf("---------------------------\n"); 22 printf("x存儲的值為:%x\n", x); 23 printf("y存儲的值為:%x\n", y); 24 printf("---------------------------\n"); 25 int *tmp = NULL; 26 tmp = x; 27 x = y; 28 y = tmp; 29 //所以交換x,y只是交換了兩者存儲的值(值為a,b的地址),並沒有涉及到a,b的值的交換 30 //所以只是操作地址並沒有卵用 31 printf("x存儲的值為:%x\n", x); 32 printf("y存儲的值為:%x\n", y); 33 printf("---------------------------\n"); 34 }
運行結果:
但是可以通過地址間接地改變實參的值(請參見例子2)
2、例子2:指針傳遞
#include <stdio.h> int main() { int a = 2, b = 3; void swap(int* x, int* y); printf("before:%d,%d\n", a, b); swap(&a, &b); printf("later:%d,%d\n", a, b); return 0; } void swap(int* x, int* y) { int tmp; //這里使用了‘*’表示操作的是指針x,y所指向變量的內容(即變量a,b的內容) tmp = *x; *x = *y; *y = tmp; }
運行結果:
二、按引用傳遞
對引用的操作等於對其指定的對象進行操作,當將實參傳遞給形參時,形參就指向了實參(形參與實參同義,是它的一個別名)
1 #include <stdio.h> 2 void swap(int& a, int& b) 3 { 4 int tmp; 5 tmp = a; 6 a = b; 7 b = tmp; 8 } 9 10 int main() 11 { 12 int i = 3, j = 4; 13 printf("before swap:i=%d,j=%d\n", i, j); 14 swap(i, j); 15 printf("After swap:i=%d,j=%d\n", i, j); 16 return 0; 17 }
運行結果:
三、補充
至於指針/引用傳遞的格式,可以參考以下的內容:
1 int x=1; 2 3 int *y=&x; //用於指針傳遞,y有自己獨立的內存地址,存儲的內容是x的地址,*y是x的值 4 5 int &z=x; //用於引用傳遞,可以理解為z就是x,x就是z,只不過名字不一樣
最后再啰嗦一個例子:
1 #include <iostream> 2 using namespace std; 3 int change1(char* name){ 4 name = "alter"; 5 return 1; 6 } 7 8 int change2(char* &name){ 9 name = "alter"; 10 return 1; 11 } 12 13 int main(){ 14 char* string ="original!"; 15 change1(string); 16 cout << string <<'\n'; 17 18 change2(string); 19 cout << string << '\n'; 20 21 }
運行結果:
change1是值傳遞,形參name有自己獨立的內存地址,修改后name的內容變成了“alter”的地址(但string的內容還是”original!“)。
change2是引用傳遞,形參name的地址就是string的地址,或者說name就是string。