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