《C與指針》讀書(shū)筆記三
函數(shù)是各種編程語(yǔ)言中都有的概念。早2000年之前,好些大學(xué)的教學(xué)課程是PASCAL。 從概念上來(lái)說(shuō)函數(shù)的概念沒(méi)有發(fā)生任何變化。函數(shù)一般是處理數(shù)據(jù)的工具,可以進(jìn)行模塊性開(kāi)發(fā)。有點(diǎn)像機(jī)械**中各個(gè)零件。將各個(gè)零件組裝起來(lái)就成為系統(tǒng)工具。也就是軟件也可以采用工程管理方法來(lái)進(jìn)行生產(chǎn),代碼重用性也得到了增強(qiáng),比如我從來(lái)沒(méi)有編寫(xiě)過(guò)冒泡的排序,只是簡(jiǎn)單的使用。
本文引用地址:http://2s4d.com/article/201608/294897.htm從返回值來(lái)劃分函數(shù)分為有返回值和沒(méi)有返回值。從參數(shù)的角度劃分可以分為有參數(shù)和無(wú)參數(shù)。在使用函數(shù)的過(guò)程中我從來(lái)沒(méi)有認(rèn)真的考慮參數(shù)的具體含義。如果靜下心來(lái)仔細(xì)考慮有覺(jué)得沒(méi)有什么深刻的意義。有一本書(shū)上介紹,參數(shù)就是函數(shù)接口。就像機(jī)械的接口,比如一臺(tái)電動(dòng)機(jī)經(jīng)過(guò)變速調(diào)整后流出的接口就是一個(gè)齒輪或者飛輪一樣。使用者可以根據(jù)齒輪或者飛輪的繼續(xù)設(shè)計(jì)傳動(dòng)機(jī)械。而不必在考慮動(dòng)力來(lái)源。
但是參數(shù)到底是什么?這個(gè)問(wèn)題我一直沒(méi)有考慮透徹過(guò)。在《C與指針》中有一段簡(jiǎn)單的描述,簡(jiǎn)單到作者根本沒(méi)有任何前后文鋪墊。作者肯定是對(duì)參數(shù)的實(shí)質(zhì)了然于胸。所以可以很平淡的敘述出參數(shù)的實(shí)質(zhì)。僅僅四個(gè)字“傳值調(diào)用”。這段話出現(xiàn)在122頁(yè),
仔細(xì)斟酌原文的每一句話。對(duì)理解函數(shù)、參數(shù)以C語(yǔ)言的調(diào)用原理甚至指針的概念非常有用。所有的參數(shù)都是傳值調(diào)用,也就對(duì)原值“復(fù)制”。既然是復(fù)制那么就對(duì)原值不會(huì)進(jìn)行人和操作。任何概念都不是孤立的,如果結(jié)合變量的作用域來(lái)理解“復(fù)制”就非常容易理解。如果再加入計(jì)算機(jī)內(nèi)存模型的概念。理解“傳值調(diào)用”就更加簡(jiǎn)單。因?yàn)橐粋€(gè)變量有兩個(gè)屬性----地址和值。既然傳值那么對(duì)原來(lái)地址就沒(méi)有任何影響。可以簡(jiǎn)單圖解。
void main( )
{
int x, y;
x = 10;
y = 20;
….. …..
}
前三條語(yǔ)句我們聲明了兩個(gè)變量---x、y,并且給兩個(gè)變量都賦值---10 、20。這當(dāng)然是文本的字面表達(dá)的意義。如果我們列出一個(gè)內(nèi)存模型來(lái)理解這三條語(yǔ)句,也就是從計(jì)算機(jī)的角度來(lái)理解能得到什么概念。可以圖解一下。
在計(jì)算機(jī)角度也該是劃分兩個(gè)地址空間0x100 00、0x100 01,并且在這個(gè)地址空間分別插入10、20的值。如果設(shè)計(jì)一個(gè)函數(shù)來(lái)修改x、y的值,其實(shí)就是對(duì)地址空間0x100 00、0x100 01的內(nèi)容進(jìn)行修改。
我們?cè)O(shè)計(jì)一個(gè)函數(shù),對(duì)x、y的的值進(jìn)行乘方,代碼如下:
int power( int dat)
{
return dat *dat;
}
x = power( x );
y = power( y );
完整代碼如下:
int power( int dat)
{
return dat *dat;
}
void main( )
{
int x, y;
x = 10;
y = 20;
x = power( x );
y = power( y );
….. …..
}
從文本角度理解,非常簡(jiǎn)單,就是通過(guò)power函數(shù)計(jì)算出某個(gè)數(shù)的平方。通過(guò)參數(shù)dat接收了x和y的值。平方后返回,通過(guò)x、y接收了返回值。如果不采用x、y接收x、y的值就不會(huì)受到影響。比如主函數(shù)代碼如下:
void main( )
{
int x, y;
x = 10;
y = 20;
power( x );
power( y );
….. …..
}
圖解原理也非常簡(jiǎn)單。
power( x ); 是將x變量(地址:0x100 00)值傳給了dat。在執(zhí)行power( x );結(jié)束時(shí),函數(shù)表達(dá)式返回的值為100. power( y );同理。
在int power( int dat)函數(shù)運(yùn)行過(guò)程中是對(duì)dat數(shù)據(jù)(地址:0x200 00)進(jìn)行處理,不會(huì)影響main函數(shù)的變量x、y的值。當(dāng)power函數(shù)結(jié)束后會(huì)釋放對(duì)地址0x200 00的控制,將他交給系統(tǒng)。系統(tǒng)可以繼續(xù)將他分配給其他變量使用。
int power( int dat) 是由返回的函數(shù),如果采用無(wú)返回的函數(shù),也可以實(shí)現(xiàn)乘方并且將乘方的結(jié)果存入x、y。代碼如下:
void power( int *dat )
{
int temp = *dat;
*dat = temp * temp;
}
void main( )
{
int x, y;
x = 10;
y = 20;
power( &x );
power( &y );
….. …..
}
power( &x ); 接收的也是值,不過(guò)不是x的值10,而是x的地址,即0x100 00。 通過(guò)對(duì) x地址的來(lái)操作x的值。這就解決的變量的作用域問(wèn)題。power( int *dat )
不能超過(guò)自己作用域去訪問(wèn)上級(jí)調(diào)用函數(shù)的變量。但是可以通過(guò)地址來(lái)訪問(wèn)到上級(jí)函數(shù)的變量。如果仔細(xì)分析該函數(shù)。我們其實(shí)可以對(duì)指針理解更深一步。
void power( int *dat )
{
int temp = *dat;
*dat = temp * temp;
}
power( &x );其實(shí)等價(jià)于power( 0x100 00 );那么temp = *dat;其實(shí)就等價(jià)于temp = *((int *)0x100 00), (int *)是整型指針,地址為0x100 00。*((int *)0x100 00)是指向0x100 00地址的解引用,返回的值為10.temp接收了該值。 *dat = temp * temp;等價(jià)于*((int *)0x100 00) = 10*10。即在0x100 00地址存入100的值。
評(píng)論