宋美英
(呂梁學(xué)院 離石師范分校,山西 呂梁 033000)
C語(yǔ)言作為一種結(jié)構(gòu)化程序設(shè)計(jì)語(yǔ)言,強(qiáng)調(diào)程序設(shè)計(jì)的風(fēng)格,提倡程序結(jié)構(gòu)的規(guī)范化,因此不可避免地需要使用函數(shù)調(diào)用,用函數(shù)作為構(gòu)件,可以開發(fā)出結(jié)構(gòu)清晰、功能齊全的大型程序.在C語(yǔ)言中,函數(shù)是程序的基本單位,一個(gè)C語(yǔ)言源程序可以由一個(gè)主函數(shù)或一個(gè)主函數(shù)和若干個(gè)其他函數(shù)組成,參數(shù)是實(shí)現(xiàn)函數(shù)間數(shù)據(jù)交換的主要通道.
在調(diào)用有參函數(shù)時(shí),主調(diào)函數(shù)與被調(diào)函數(shù)之間有數(shù)據(jù)傳遞關(guān)系.定義函數(shù)時(shí),出現(xiàn)在函數(shù)首部的參數(shù)稱為“形式參數(shù)”(簡(jiǎn)稱“形參”).主調(diào)函數(shù)中,調(diào)用函數(shù)時(shí),函數(shù)名后面圓括號(hào)中所使用的參數(shù)稱為“實(shí)際參數(shù)”(簡(jiǎn)稱“實(shí)參”).實(shí)參與形參應(yīng)保持個(gè)數(shù)一致、類型相同或兼容.
形參與實(shí)參占用不同的存儲(chǔ)單元.作為局部變量,形參只在本函數(shù)體內(nèi)有效.在未發(fā)生函數(shù)調(diào)用時(shí),形參并不占用內(nèi)存中的存儲(chǔ)單元.只有在發(fā)生函數(shù)調(diào)用時(shí),才為形參分配內(nèi)存單元,同時(shí)將實(shí)參的值傳遞給被調(diào)函數(shù)的形參.在函數(shù)調(diào)用結(jié)束后,釋放形參所占的內(nèi)存單元.
在C語(yǔ)言中,參數(shù)間的數(shù)據(jù)傳遞是單向的,即數(shù)據(jù)只能由實(shí)參傳給形參,而不能由形參傳回給實(shí)參.根據(jù)參數(shù)類型的不同,可以將參數(shù)間的數(shù)據(jù)傳遞方式分為“值傳遞”和“地址傳遞”兩種.下面通過(guò)幾個(gè)交換問(wèn)題的具體執(zhí)行過(guò)程探討C語(yǔ)言中函數(shù)參數(shù)的傳遞問(wèn)題.
當(dāng)參數(shù)為普通類型時(shí),形參變量與實(shí)參變量占用不同的內(nèi)存空間,形參的改變并不能影響所對(duì)應(yīng)的實(shí)參的值.
[例1] void swap1(int x, int y)
{ int t;
t=x; x=y; y=t;
}
main( )
{ int a=5, b=9;
swap1(a,b);
printf(“a=%d,b=%d ”,a,b);
}
程序運(yùn)行結(jié)果為:
a=5,b=9
由輸出結(jié)果可以看出,實(shí)參變量a、b的值并沒(méi)有發(fā)生交換.例1中各變量值的變化情況如圖1所示.
圖1 參數(shù)為普通類型時(shí)各變量變化情況
發(fā)生函數(shù)調(diào)用時(shí),為形參x和y分配內(nèi)存空間,同時(shí)實(shí)參把自己的值復(fù)制一份依次傳遞給形參,形參x和y分別得到5和9,然后形參使用得到的值參與被調(diào)函數(shù)中的運(yùn)算.事實(shí)上,在值傳遞的過(guò)程中,有一項(xiàng)操作隱含在被調(diào)函數(shù)中.這個(gè)隱含操作確實(shí)存在,如果把它顯式地寫出來(lái),可得被調(diào)函數(shù)如下:
void swap1(int x, int y)
{ int t;
x=a; y=b; //執(zhí)行被調(diào)函數(shù)時(shí)的隱含操作
t=x; x=y; y=t;
}
現(xiàn)在問(wèn)題變得清晰起來(lái),發(fā)生函數(shù)調(diào)用時(shí),只是隱含地把實(shí)參a、b的值通過(guò)賦值的方式傳遞給了形參x、y,形參并沒(méi)有代替實(shí)參,修改形參也就并不意味著修改了實(shí)參.因此,在被調(diào)函數(shù)中交換了形參變量x和y的值,函數(shù)調(diào)用結(jié)束時(shí),釋放形參所占用的存儲(chǔ)空間并返回主函數(shù),此時(shí)形參x、y不復(fù)存在,而實(shí)參a和b的值并沒(méi)有發(fā)生變化.
當(dāng)實(shí)參為變量的地址、指針變量或數(shù)組名等實(shí)質(zhì)上表示地址的形式時(shí),形參應(yīng)使用指針變量或數(shù)組名.發(fā)生函數(shù)調(diào)用時(shí),由形參接收實(shí)參中的地址值,此時(shí),形參與實(shí)參指向同一段存儲(chǔ)單元.如果在被調(diào)函數(shù)中修改形參指針?biāo)赶虻牡刂分械膬?nèi)容,那么主調(diào)函數(shù)中變量的值也會(huì)發(fā)生同步改變.
[例2] void swap2(int *x, int *y)
{ int t;
t=*x; *x=*y; *y=t;
}
main( )
{ int a=5, b=9;
int *p1=&a, *p2=&b;
swap2(p1, p2);
printf(“a=%d, b=%d ”,a,b);
}
程序運(yùn)行結(jié)果為:
a=9,b=5
由輸出結(jié)果可以看出,主函數(shù)中的變量a、b的值發(fā)生了交換.例2中各變量值的變化情況如圖2所示.
圖2 參數(shù)為指針類型且交換指針?biāo)竷?nèi)容時(shí)各變量變化情況
主函數(shù)中,實(shí)參指針變量p1和p2分別存放a、b的地址,發(fā)生函數(shù)調(diào)用時(shí),傳遞的并不是變量的值,而是變量的地址,即將a、b的地址傳給了形參指針x和y,這就是所謂的“地址傳遞”.其實(shí)它與值傳遞相同,同樣在被調(diào)函數(shù)中有一項(xiàng)隱含操作如下:
void swap2(int *x, int *y)
{ int t;
x=&a; y=&b; //執(zhí)行被調(diào)函數(shù)時(shí)的隱含操作
t=*x; *x=*y; *y=t;
}
由隱含的賦值操作可以看出,形參指針x和y分別存放a、b變量的地址值.接下來(lái)執(zhí)行被調(diào)函數(shù)時(shí),對(duì)*x和*y的操作也就是對(duì)a、b變量本身的操作.因此,交換了*x和*y的值,也就是交換了形參指針變量所指向地址中的內(nèi)容.函數(shù)調(diào)用結(jié)束返回主函數(shù)時(shí),釋放形參所占的單元,不存在了的只是形參指針變量x和y,它們?cè)瓉?lái)所指向單元中修改過(guò)的值被保留下來(lái).本例主函數(shù)中的變量實(shí)現(xiàn)交換,這只是利用了指針對(duì)變量的間接訪問(wèn)方式,使用指針變量作參數(shù),從而實(shí)現(xiàn)對(duì)主調(diào)函數(shù)中變量值的修改,這并不是由于數(shù)據(jù)從形參傳回給了實(shí)參,實(shí)參向形參的單向數(shù)據(jù)傳遞性是不變的.因此,有的文獻(xiàn)將地址傳遞描述為“雙向傳遞”是不妥當(dāng)?shù)?
[例3] void swap3(int *x, int *y)
{ int *t;
t=x; x=y; y=t;
}
main( )
{ int a=5,b=9;
int *p1=&a,*p2=&b;
swap3(p1,p2);
printf(“a=%d,b=%d ”,a,b);
}
程序運(yùn)行結(jié)果為:
a=5,b=9
由輸出結(jié)果可知,使用指針變量作參數(shù),也不一定能夠改變主調(diào)函數(shù)中變量的值.這是因?yàn)殡m然同例2相同,本例中的參數(shù)傳遞方式依然是地址傳遞,但函數(shù)swap3( )只是交換了x和y中所存放的地址,即改變了兩個(gè)指針的指向,并沒(méi)有改變指針?biāo)竼卧械闹?,因此主函?shù)中兩個(gè)變量的值并沒(méi)有被交換.例3中各變量值的變化情況如圖3所示.
圖3 參數(shù)為指針類型且交換指針變量本身時(shí)各變量變化情況
C語(yǔ)言中,一般將函數(shù)參數(shù)的傳遞方式分為值傳遞和地址傳遞兩種,這只是根據(jù)參數(shù)類型的不同而進(jìn)行的一種分類.值傳遞指參數(shù)為普通類型時(shí)的參數(shù)傳遞,而地址傳遞一般指參數(shù)的實(shí)質(zhì)是地址類
的參數(shù)傳遞.事實(shí)上,無(wú)論參數(shù)的類型如何,參數(shù)間的數(shù)據(jù)傳遞方式都是單向的,即只能由實(shí)參傳遞給形參,值傳遞和地址傳遞的區(qū)別僅在于傳遞的數(shù)據(jù)類型不同.
參考文獻(xiàn):
[1]董漢麗.C語(yǔ)言程序設(shè)計(jì)[M].大連:大連理工大學(xué)出版社,2009.
[2]譚浩強(qiáng).C程序設(shè)計(jì)(第四版)[M].北京:清化大學(xué)出版社,2010.
[3]董鑫正.C語(yǔ)言教學(xué)中函數(shù)參數(shù)傳遞問(wèn)題的探討[J].電腦知識(shí)與技術(shù),2012(7).
[4]馬新.C語(yǔ)言函數(shù)間參數(shù)傳遞機(jī)制的探討[J].白城師范學(xué)院學(xué)報(bào),2008(6).