這兩天做日曆系統小專案,發現了乙個很關鍵的問題:函式傳參問題。
1、傳值呼叫和傳址呼叫(swap函式為例):
傳值呼叫現象:x和y作為實參,在進入函式的時候是只拷貝了乙份自己的副本(副本具有和自己一樣的值,但是變數 不同。)
所以我們在子函式swap中交換的實際是副本而不是x,y的真身。
所以在swap內部確實是換了,但是到外部的x和y根本沒有受影響。
傳「址」呼叫現象:執行完swap函式後main函式中的x和y被真實改變了。(但是x和y的真身還是沒有進入swap函式, 而是swap函式內部跑出來把外面的x和y的真身改變了)
實際上實參x和y真身永遠無法進入swap函式(子函式),但是這次我們是把x和y的位址穿進去給子函式了,於是在子函式內可以用指標的方式從函式內部訪問到外部的x和y真身,從而改變x和y的值。
2、函式形參和返回值
(1)函式名是乙個符號,表示整個函式**段的首位址,其實質是乙個指標常量,所以在程式中使用到函式名時都是當位址用的,表示呼叫該函式。函式體是函式的關鍵,由一對{}括起來,包含很多句**,函式體就是函式實際做的工作。
形參是函式的輸入部分;
返回值是函式的輸出部分。
(2)若沒有形參列表和返回值,函式也能對資料進行加工,使用全域性變數即可。
用全域性變數來傳參和用函式引數列表返回值來傳參各有特點,在實踐中都有使用。
總的來說,函式引數傳參用得較多,因為這樣可實現模組化程式設計,而c語言中也是儘量減少使用全域性變數。
(3)全域性變數傳參最大的好處就是省略了函式傳參的開銷,所以效率要高一些;
但是實戰中用的最多的還是函式傳參,如果引數很多傳參開銷非常大,通常的做法是把很多引數打包成乙個結構體,然後傳結構體變數指標進去。
3、結構體變數作為函式形參
(1)結構體變數作為函式形參的時候,實際上和普通變數(類似於int之類的)傳參時表現是一模一樣的。所以說結構體變數其實也是普通變數而已。
(2)因為結構體一般都很大,所以如果直接用結構體變數進行傳參,那麼函式呼叫效率就會很低。
(因為在函式傳參的時候需要將實參賦值給形參,所以當傳參的變數越大呼叫效率就會越低)
為提高效率,我們可改傳變數的指標(位址)進去。
(3)結構體因為自身太大,所以傳參應該用指標來傳
4、陣列和指標作為函式形參
(1)陣列名作為形參傳參時,實際傳遞是不是整個陣列,而是陣列的首元素的首位址。所以在子函式內部,傳進來的陣列名就等於是乙個指向陣列首元素首位址的指標。所以sizeof得到的是4。 (但是要注意陣列名是長指標不能改變其指向的!!!)
(2)在子函式內傳參得到的陣列首元素首位址,和外面得到的陣列首元素首位址是相同的。這就是所謂的」傳址呼叫」,即呼叫子函式時傳了位址,此時可通過傳進去的位址訪問實參。
(3)陣列名作為函式形參時,裡的數字可有可無。因為陣列名做為形參傳遞的實際只是個指標,根本沒有陣列長度這個資訊。
(4)指標作為函式形參時和陣列作為函式形參是一樣的.這就好像指標方式訪問陣列元素和陣列方式訪問陣列元素的結果一樣是一樣的。(這裡的指標作為函式形參就相當於函式傳『址』)。
5、函式傳參中使用const指標
(1)const用來修飾指標作函式傳參,就是為了宣告在函式內部不會改變該指標所指向的變數。所以給該函式傳乙個不可改變的指標
(譬如char *p = 「
linux
」; 字串常量,放在**段中,不可改變)後,一旦該函式內部試圖更改它時編譯器會提示錯誤;
而乙個未宣告為const指標引數的函式,我們給該函式傳乙個不可更改的指標時,一旦該函式內部更改它後,編譯器在編譯過程中不會有提示,而是會在執行中導致段錯誤。
(2)一般來說,函式的輸入部分就是函式引數,輸出部分就是返回值。問題是函式的引數可以有很多個,而返回值只能有乙個。則我們無法讓乙個函式返回多個值。
(3)現實程式設計中,乙個函式需要返回多個值是非常普遍的,因此完全依賴於返回值是不靠譜的,通常的做法是用引數來做返回
(在典型的linux風格函式中,返回值是不用來返回結果的,而是用來返回0或者負數用來表示程式執行結果是對還是錯,是成功還是失敗)。
(4)普遍做法,程式設計中函式的輸入和輸出都是靠函式引數的,返回值只是用來表示函式執行的結果是對(成功)還是錯(失敗)。如果這個引數是用來做輸入的,就叫輸入型引數;如果這個引數的目的是用來做輸出的,就叫輸出型引數。輸出型引數就是用來讓函式內部把資料輸出到函式外部的。
(5)總結:函式傳參如果傳的是普通變數(不是指標)那肯定是輸入型引數;若該函式形參是指標變數並且加了const,那麼就表示這個引數是用來做輸入型引數的;若該函式形參是指標變數並且還沒加const,那麼就表示這個引數是用來做輸出型引數的。
譬如c庫函式中strcpy函式:char *strcpy(char *dest, const char *src);。
C C 傳參問題
1 結構體變數作為函式形參的時候,實際上和普通變數 類似於int之類的 傳參時表現是一模一樣的。所以說結構體變數其實也是普通變數而已。2 因為結構體一般都很大,所以如果直接用結構體變數進行傳參,那麼函式呼叫效率就會很低。因為在函式傳參的時候需要將實參賦值給形參,所以當傳參的變數越大呼叫效率就會越低 ...
C C 函式中陣列傳參
voidf char s char str hello world cout sizeof str strlen str f str 以上 在32位平台上輸出為 12,11,4,11 原因 在c c 裡陣列作為引數時傳遞的實際上是指向陣列第乙個元素的指標,因此sizeof str 返回的是指標的大小...
C C 陣列傳參
託管c 可以將陣列作為輸入 輸出引數。clr封裝c 託管介面時,可以使用cli array 作為輸入引數,而且c 可以獲取到c 修改後的陣列內容。array陣列原型 qualifiers cli array qualifiers type dimension var 我們只關注下模板引數 type ...