C语言有参函数调用时参数间数据传递问题
C語言中在發(fā)生有參函數(shù)調(diào)用時,實參變量與形參變量之間的數(shù)據(jù)都是單向的“值傳遞”方式。包括指針變量和數(shù)組名作參數(shù)的情況。
C語言要求函數(shù)的實參要有確定的值,在函數(shù)調(diào)用時給形參分配相應(yīng)的內(nèi)存單元,同時將實參的“值”賦(復(fù)制)給形參,實現(xiàn)數(shù)據(jù)從實參到形參的傳遞(‘值傳遞’方式)。因為是復(fù)制,所以在操作副本(形參)過程中不會影響到原本(實參)內(nèi)容。
首先,作為函數(shù)實參的量包括常量、變量和表達式。其中變量又包括簡單變量、數(shù)組元素、數(shù)組名、指針變量等。不同類型變量作參數(shù)實現(xiàn)的數(shù)據(jù)傳遞方式相同,效果不同。所謂方式相同即都是參數(shù)間數(shù)據(jù)單向的“值傳遞”,效果不同是指被調(diào)函數(shù)能否改變主調(diào)函數(shù)中變量的值。
情況一:簡單變量或數(shù)組元素作為函數(shù)參數(shù)
數(shù)組元素本身屬于簡單變量,在向形參傳遞數(shù)據(jù)時,根據(jù)前述規(guī)則只需將變量中的“值”復(fù)制一份放到形參變量中去操作,此時在被調(diào)用函數(shù)中操作的對象(形參)與實參并不在同一內(nèi)存單元,并且在調(diào)用結(jié)束后形參所占內(nèi)存單元被釋放,因此調(diào)用函數(shù)不會影響到實參變量的值。同時被調(diào)函數(shù)也不會影響到主調(diào)函數(shù)中其他變量的值。
例: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);}
情況二:指針變量或數(shù)組名作為函數(shù)參數(shù)
1.指針變量作函數(shù)參數(shù)
指針變量作實參在調(diào)用時仍然符合前述“值傳遞”規(guī)則,將其“值”賦給形參,相當于復(fù)制。此時數(shù)據(jù)在實參與形參間傳遞仍是單向的,調(diào)用函數(shù)不會影響實參的“值”(即指針變量中所存地址)。而與簡單變量不同的是指針變量復(fù)制給形參的“值”本身是一個地址,這個地址為形參訪問其所指變量創(chuàng)造了可靠條件。我的理解是,實參是一個抽屜的鑰匙,在傳參時,實參復(fù)制了一把鑰匙傳給形參。而被調(diào)函數(shù)拿到鑰匙副本后,進行的操作可以分為兩類:1、對鑰匙本身做了一些操作(對指針本身進行操作);2、通過鑰匙對抽屜里的內(nèi)容進行了一些操作(?對指針所指的變量進行操作);兩種操作都不可能影響實參的值(即鑰匙原本),卻有可能改變實參所指向變量的值(即抽屜里的內(nèi)容)。
例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.數(shù)組名作函數(shù)參數(shù)
數(shù)組名本身是一個特殊的指針變量,其值是數(shù)組的首地址,因此作實參時其傳給形參的是內(nèi)存中某指定單元的地址,調(diào)用過程中形參數(shù)組與實參數(shù)組占用同一段內(nèi)存單元,因此對形參數(shù)組的操作也就是對實參數(shù)組的操作,對實參數(shù)組與形參數(shù)組來說數(shù)據(jù)傳遞表現(xiàn)為“雙向”的,而對實參變量與形參變量而言數(shù)據(jù)的傳遞仍然是單向的。
例
#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]++;
}
情況三:引用作為函數(shù)參數(shù):
首先申明引用和指針最大的不同是:引用本身不是變量,不存在自己的變量空間,引用只是一個作為變量別名的標志。
引用必須依托于一個已實際存在的變量,正如一個人的如果連正名都沒有,就無所謂小名了。正因為引用只是為了方便為同一個變量所取的小名,所以在任何地方通過引用對變量的操作和通過變量名進行操作的結(jié)果是一樣的。
綜上,當引用作為函數(shù)參數(shù)時,對形參的操作既是對原變量的操作,可以改變實參的值。效果上雖然和通過指針改變實參一樣,但兩種機制完全不同,引用并沒有另開辟其它空間,直接對“原本”進行了操作,節(jié)省了時間和空間。
(拓)結(jié)構(gòu)體數(shù)組作函數(shù)參數(shù)
用結(jié)構(gòu)體數(shù)組作函數(shù)參數(shù)包含兩類情況:結(jié)構(gòu)體數(shù)組元素作實參和結(jié)構(gòu)體數(shù)組名作實參。兩類情況仍然服從數(shù)據(jù)的單向傳遞原則只不過前者傳給形參的是某些變量的值,后者傳給形參的是結(jié)構(gòu)體數(shù)組的首地址。
1.結(jié)構(gòu)體數(shù)組元素作實參
符合結(jié)構(gòu)體變量作實參規(guī)則,采取單向“值傳遞”方式將結(jié)構(gòu)體變量所占的內(nèi)存單元的內(nèi)容全部順序復(fù)制給形參(函數(shù)調(diào)用期間形參也要占用內(nèi)存單元)。注意當實參的成員中包含數(shù)組時形參相應(yīng)的成員接受到的是一個地址。
2.結(jié)構(gòu)體數(shù)組名實參
同整形數(shù)組數(shù)組名作實參一樣傳遞給形參的是內(nèi)存中已指定單元的地址,調(diào)用過程中形參數(shù)組與實參數(shù)組占用同一段內(nèi)存單元,因此對形參數(shù)組的操作也就是對實參數(shù)組的操作。對數(shù)組的操作表現(xiàn)為雙向性。
綜上所述,對于有參函數(shù)調(diào)用時,實參變量與形參變量之間的數(shù)據(jù)都是單向的“值傳遞”方式。至于調(diào)用過程中是否會改變主調(diào)函數(shù)中變量的值,則只需根據(jù)具體算法看被調(diào)函數(shù)是否會找到主調(diào)函數(shù)中變量所在內(nèi)存單元并對其原本進行操作。
總結(jié)
以上是生活随笔為你收集整理的C语言有参函数调用时参数间数据传递问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 集成方法Ensemble Method(
- 下一篇: 卷积在计算机中实现+pool作用+数据预