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