C語言有參函數調用時參數值傳遞問題

再談C語言有參函數調用時參數值傳遞問題

分類: C/C++ 1637人閱讀 評論(0)收藏舉報

C語言有參函數調用時參數間數據傳遞問題

C語言中在發生有參函數調用時,實參變量與形參變量之間的數據都是單向的“值傳遞”方式。包括指針變量和數組名作參數的情況。

C語言要求函數的實參要有確定的值,在函數調用時給形參分配相應的內存單元,同時將實參的“值”賦(複製)給形參,實現數據從實參到形參的傳遞(‘值傳遞’方式)。因爲是複製,所以在操作副本(形參)過程中不會影響到原本(實參)內容。

首先,作爲函數實參的量包括常量、變量和表達式。其中變量又包括簡單變量、數組元素、數組名、指針變量等。不同類型變量作參數實現的數據傳遞方式相同,效果不同。所謂方式相同即都是參數間數據單向的“值傳遞”,效果不同是指被調函數能否改變主調函數中變量的值。


情況一:簡單變量或數組元素作爲函數參數

數組元素本身屬於簡單變量,在向形參傳遞數據時,根據前述規則只需將變量中的“複製一份放到形參變量中去操作,此時在被調用函數中操作的對象(形參)與實參並不在同一內存單元,並且在調用結束後形參所佔內存單元被釋放,因此調用函數不會影響到實參變量的值。同時被調函數也不會影響到主調函數中其他變量的值。

例:1
#include<stdio.h>
void main()
{
	int a=1,f(int a);
	printf("%d%d",a,f(a));
}
f(int a)
{
	return(++a);
}
例2
#include<stdio.h>
void main()
{
	int a[3]={1,2,3},f(int a);
	printf("%d%d",a[0],f(a[0]));
}
f(int a)
{
	return(++a);
}



情況二:指針變量數組名作爲函數參數

1.指針變量作函數參數

指針變量作實參在調用時仍然符合前述“值傳遞”規則,將其“值”賦給形參,相當於複製。此時數據在實參與形參間傳遞仍是單向的,調用函數不會影響實參的“”(即指針變量中所存地址)。而與簡單變量不同的是指針變量複製給形參的“”本身是一個地址,這個地址爲形參訪問其所指變量創造了可靠條件。我的理解是,實參是一個抽屜的鑰匙,在傳參時,實參複製了一把鑰匙傳給形參。而被調函數拿到鑰匙副本後,進行的操作可以分爲兩類:1、對鑰匙本身做了一些操作(對指針本身進行操作);2、通過鑰匙對抽屜裏的內容進行了一些操作( 對指針所指的變量進行操作);兩種操作都不可能影響實參的值(即鑰匙原本),卻有可能改變實參所指向變量的值(即抽屜裏的內容)。

例1
#include<stdio,h>
void main()
{
	void swap(int*p1,int*p2);
	int a,b;
	int *pointer1,int*pointer2;
	scanf("%d,%d",&a,&b);
	pointer1=&a; pointer2=&b;
	if(a<b) swap(pointer1,pointer2);
	printf("%d,%d",a,b);
}
void swap(int*p1,int*p2)
{
	int temp;
	temp=*p1;
	*p1=*p2;
	*p2=temp;
}
例2
#include<stdio,h>
void main()
{
	void swap(int*p1,int*p2);
	int a,b;
	int *pointer1,int*pointer2;
	scanf("%d,%d",&a,&b);
	pointer1=&a; pointer2=&b;
	if(a<b)
	swap(pointer1,pointer2);
	printf("%d,%d",a,b);
}
void swap(int*p1,int*p2)
{
	int temp;
	temp=p1;
	p1=p2;
	p2=temp;
}

2.數組名作函數參數

數組名本身是一個特殊的指針變量,其值是數組的首地址,因此作實參時其傳給形參的是內存中某指定單元的地址,調用過程中形參數組與實參數組佔用同一段內存單元,因此對形參數組的操作也就是對實參數組的操作,對實參數組形參數組來說數據傳遞表現爲“雙向”的,而對實參變量形參變量而言數據的傳遞仍然是單向的。

例
#include<stdio,h>
void main()
{
	int a[3]={1,2,3};
	void f(int a[]);
	f(a);
	for(i=0;i<3;i++)
	printf("%d",a[i]);
}
void f(int a[])
{
	for(i=0;i<3;i++)
	a[i]++;
}


情況三:引用作爲函數參數:

首先申明引用和指針最大的不同是:應用本身不是變量,不存在自己的變量空間,引用只是一個作爲變量別名的標誌。

引用必須依託於一個已實際存在的變量,正如一個人的如果連正名都沒有,就無所謂小名了。正因爲引用只是爲了方便爲同一個變量所取的小名,所以在任何地方通過引用對變量的操作和通過變量名進行操作的結果是一樣的。

綜上,當引用作爲函數參數時,對形參的操作既是對原變量的操作,可以改變實參的值。效果上雖然和通過指針改變實參一樣,但兩種機制完全不同,引用並沒有另開闢其它空間,直接對“原本”進行了操作,節省了時間和空間。


(拓)結構體數組作函數參數

用結構體數組作函數參數包含兩類情況:結構體數組元素作實參和結構體數組名作實參。兩類情況仍然服從數據的單向傳遞原則只不過前者傳給形參的是某些變量的值,後者傳給形參的是結構體數組的首地址。

1.結構體數組元素作實參

符合結構體變量作實參規則,採取單向“值傳遞”方式將結構體變量所佔的內存單元的內容全部順序複製給形參(函數調用期間形參也要佔用內存單元)。注意當實參的成員中包含數組時形參相應的成員接受到的是一個地址。

2.結構體數組名實參

同整形數組數組名作實參一樣傳遞給形參的是內存中已指定單元的地址,調用過程中形參數組與實參數組佔用同一段內存單元,因此對形參數組的操作也就是對實參數組的操作。對數組的操作表現爲雙向性。

綜上所述,對於有參函數調用時,實參變量與形參變量之間的數據都是單向的“值傳遞”方式。至於調用過程中是否會改變主調函數中變量的值,則只需根據具體算法看被調函數是否會找到主調函數中變量所在內存單元並對其原本進行操作。

11
0
發佈了1 篇原創文章 · 獲贊 9 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章