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