C中實參與形參的“值傳遞”只能“單向傳送”(透徹的理解)

今天又徹底地把這部分知識回顧了一下,好好地理解了一番。還是記下來比較靠譜,加深印象,省的以後再忘。

主調函數(比如main函數)中,調用函數(比如numpp函數)時,如果swap的參數在函數中改變了,那麼此參數必須是指針類型的。還是例子好說話。

目的:實現main中的一個整形變量加1。(當然實際情況,如果簡單的功能,不會採取調用函數方式,僅作說明)

錯誤的例子

void numpp(int x)
{
	x++;
}
main()
{
	int a=2;
	numpp(a);
	printf("a=%d\n",a);
}
上述代碼運行結果爲:a=2,並沒有加1。

正確的寫法爲:

void numpp(int *x)
{
	(*x)++;
}
main()
{
	int a=2;
	numpp(&a);
	printf("a=%d\n",a);
}
這次的運行結果是正確的:a=3。

這是爲什麼呢?

錯誤的例子分析:main中,a=2,調用numpp函數時,實參a的值傳如x,然後x+1,於是x=3,函數調用結束後,x被釋放掉,而a的值依舊沒有改變,還是2,形參x的值並不會再傳給a,只能實參向形參單向傳送。

正確的例子分析:main中,a=2,&a是a的地址,即指針,調用numpp函數時,a的指針傳送給指針變量x,那麼x就指向了變量a,(*x)++,也就是x指向的變量加1,也就是a+1,變成了3,函數調用結束後,x被釋放掉,但a的變化被保留了下來,所以是加1後的值3。

總結1:“單向傳送”的“值傳遞”方式,就是形參值的改變不能改變實參的值。不可能通過執行調用函數改變實參變量的值,但是可以改變實參指針變量所指向的變量的值。

經驗:爲了使函數中改變了的變量值能被主調函數所用,不能把要改變值的變量作爲函數參數,而應該用指針變量作爲函數參數。在函數執行過程中,使指針變量所指向的變量值發生變化,函數調用結束後,這些變量值的變化依然保留下來。

其實還有一個經典的例子,就是swap函數,交換兩個變量的值。

兩個經典的錯誤:

1、

void swap(int x,int y)
{
	int t;
	t=x;
	x=y;
	y=t;
}
main()
{
	int a,b;
	int *p1=&a,*p2=&b;
	swap(p1,p2);
	printf("a=%d,b=%d\n",a,b);
}

2、 

void swap(int *x,int *y)
{
	int *tp;
	tp=x;
	x=y;
	y=tp;
}
main()
{
	int a,b;
	int *p1=&a,*p2=&b;
	swap(p1,p2);
	printf("a=%d,b=%d\n",*p1,*p2);
}

例1中的錯誤同最上面的錯誤一樣,必須用指針變量做參數才行。但例2中,就是用指針變量做的參數,但還是不對,下面分析一下:main中,p1指向a,p2指向b,調用函數swap時,p1的值傳送給x,p2的值傳送給y,也就是說x指向a,y指向b,在函數中,x和y作了交換,於是x指向b,y指向a。但是,形參x和y的值並不會回頭再傳給實參p1和p2,所以p1依舊指向a,p2依舊指向b。a和b的值也依舊沒有改變。

總結2:其實本質跟總結1一樣。“單向傳送”的“值傳遞”方式,就是形參值的改變不能改變實參的值。不可能通過執行調用函數改變實參指針變量的值,但是可以改變實參指針變量所指向的變量的值。

最後總結:函數執行過程中,不能通過改變形參變量的值,也不能通過改變形參指針變量的值,來改變實參變量或實參指針變量,而是通過改變形參指針變量指向的變量值,來改變實參變量的值。

如果這句話看明白了,那就真正理解了。

還有一句話可以體會一下:函數的調用,只可以得到一個返回值(即函數值),而使用指針變量做參數,可以得到多個變化了的值。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章