24 C語言函式傳參詳解

2021-07-10 16:18:29 字數 3319 閱讀 1920

24.1.普通變數作為函式形參

(1)普通變數作為引數在函式傳參時,形參和實參名字可以相同也可以不同,實際上都是用實參來替代相應的形參的。

(2)在字函式內部,形參的值等於實參。原因是函式呼叫時把實參的值賦值給了形參。這就是所謂的」傳值呼叫」,相當於實參做右值,形參做左值。

24.2.陣列和指標作為函式形參

(1)函式名作為形參傳參時,實際傳遞是不是整個陣列,而是陣列的首元素的首位址。所以在子函式內部,傳進來的陣列名就等於是乙個指向陣列首元素首位址的指標。所以sizeof得到的是4。

(2)在子函式內傳參得到的陣列首元素首位址,和外面得到的陣列首元素首位址是相同的。這就是所謂的」傳址呼叫」,即呼叫子函式時傳了位址,此時可通過傳進去的位址訪問實參。

(3)陣列名作為函式形參時,裡的數字可有可無。因為陣列名做為形參傳遞的實際只是個指標,根本沒有陣列長度這個資訊。

(4)指標作為函式形參時和陣列作為函式形參是一樣的.這就好像指標方式訪問陣列元素和陣列方式訪問陣列元素的結果一樣是一樣的。

24.3.結構體變數作為函式形參

(1)結構體變數作為函式形參的時候,實際上和普通變數(類似於int之類的)傳參時表現是一模一樣的。所以說結構體變數其實也是普通變數而已。

(2)因為結構體一般都很大,所以如果直接用結構體變數進行傳參,那麼函式呼叫效率就會很低。(因為在函式傳參的時候需要將實參賦值給形參,所以當傳參的變數越大呼叫效率就會越低)。為提高效率,我們可改傳變數的指標(位址)進去。

(3)結構體因為自身太大,所以傳參應該用指標來傳(但是程式設計師可以自己決定,你非要傳結構體變數過去c語言也是允許的,只是效率低了)。

24.4.傳值呼叫與傳址呼叫

(1)傳值呼叫描述的是這樣一種現象:x和y作為實參,自己並沒有真身進入swap1函式內部,而只是拷貝了乙份自己的副本(副本具有和自己一樣的值,但是是不同的變數)進入子函式swap1,然後我們在子函式swap1中交換的實際是副本而不是x、y真身。所以在swap1內部確實是交換了,但是到外部的x和y根本沒有受影響。

(2)在swap2中x和y真的被改變了(但是x和y真身還是沒有進入swap2函式內,而是swap2函式內部跑出來把外面的x和y真身改了)。實際上實參x和y永遠無法真身進入子函式內部(進去的只能是乙份拷貝),但是在swap2我們把x和y的位址傳進去給子函式了,於是乎在子函式內可以通過指標解引用方式從函式內部訪問到外部的x和y真身,從而改變x和y。

(3)結論:這個世界上根本沒有傳值和傳址這兩種方式,c語言本身函式呼叫時一直是傳值的,只不過傳的值可以是變數名,也可以是變數的指標。

24.5.函式形參和返回值

(1)函式名是乙個符號,表示整個函式**段的首位址,其實質是乙個指標常量,所以在程式中使用到函式名時都是當位址用的,表示呼叫該函式。函式體是函式的關鍵,由一對{}括起來,包含很多句**,函式體就是函式實際做的工作。形參列表和返回值,形參是函式的輸入部分,返回值是函式的輸出部分。

(2)若沒有形參列表和返回值,函式也能對資料進行加工,使用全域性變數即可。用全域性變數來傳參和用函式引數列表返回值來傳參各有特點,在實踐中都有使用。總的來說,函式引數傳參用得較多,因為這樣可實現模組化程式設計,而c語言中也是儘量減少使用全域性變數。

(3)全域性變數傳參最大的好處就是省略了函式傳參的開銷,所以效率要高一些;但是實戰中用的最多的還是函式傳參,如果引數很多傳參開銷非常大,通常的做法是把很多引數打包成乙個結構體,然後傳結構體變數指標進去。

24.6.函式傳參中使用const指標

(1)const用來修飾指標作函式傳參,就是為了宣告在函式內部不會改變該指標所指向的變數。所以給該函式傳乙個不可改變的指標(譬如char *p = 「linux」; 字串常量,放在**段中,不可改變)後,一旦該函式內部試圖更改它時編譯器會提示錯誤;而乙個未宣告為const指標引數的函式,我們給該函式傳乙個不可更改的指標時,一旦該函式內部更改它後,編譯器在編譯過程中不會有提示,而是會在執行中導致段錯誤。

(2)一般來說,函式的輸入部分就是函式引數,輸出部分就是返回值。問題是函式的引數可以有很多個,而返回值只能有乙個。則我們無法讓乙個函式返回多個值。

(3)現實程式設計中,乙個函式需要返回多個值是非常普遍的,因此完全依賴於返回值是不靠譜的,通常的做法是用引數來做返回(在典型的linux風格函式中,返回值是不用來返回結果的,而是用來返回0或者負數用來表示程式執行結果是對還是錯,是成功還是失敗)。

(4)普遍做法,程式設計中函式的輸入和輸出都是靠函式引數的,返回值只是用來表示函式執行的結果是對(成功)還是錯(失敗)。如果這個引數是用來做輸入的,就叫輸入型引數;如果這個引數的目的是用來做輸出的,就叫輸出型引數。輸出型引數就是用來讓函式內部把資料輸出到函式外部的。

(5)總結:函式傳參如果傳的是普通變數(不是指標)那肯定是輸入型引數;若該函式形參是指標變數並且加了const,那麼就表示這個引數是用來做輸入型引數的;若該函式形參是指標變數並且還沒加const,那麼就表示這個引數是用來做輸出型引數的。譬如c庫函式中strcpy函式:char *strcpy(char *dest, const char *src);。

24.func_param

/* * 公司:***x

* 部落格:

* github:

* 專案:c語言函式傳參詳解

* 功能:演示普通變數和結構體變數在函式中傳參。

*/#include

struct a

;void func2(struct a *b)

void func1(int b)

int main(int argc, char **argv)

; func2(&d);

printf("&d = %p.\n", &d); // &d = 0xbffaafc4.

printf("d.e = %d.\n", d.e); // d.e = 10.

printf("d.f = %d.\n", d.f); // d.f = 1.

return

0;}

24.input_output_param

/* * 公司:***x

* 部落格:

* github:

* 專案:c語言函式傳參詳解

* 功能:演示輸入型引數和輸出型引數。

*/#include

#if 0

void func1(const

char *p);

#endif

void func2(char *p);

int main(int argc, char **argv)

#if 0

void func1(const

char *p)

#endif

void func2(char *p)

golang函式傳參詳解

golang中的基本型別分為值型別和引用型別 參考go中的值型別和引用型別 1.值傳遞 2.引用傳遞 注 golang函式傳參都是以複製變數的方式,不支援引用的方式 特殊的是 go語言閉包函式對外部變數是以引用的方式使用 參考由 go語言閉包函式對外部變數是以引用的方式使用 引發的閉包 摘自go語言...

Python基礎資料型別 函式傳參詳解

python基礎資料型別 函式傳參詳解 一.位置引數 1 usr bin env python2 coding utf 8 3 author yinzhengjie4 blog email y1053419035 qq.com67 站在函式定義的角度上 8def func a,b,c 位置引數,如果...

python函式的萬能引數傳參詳解

這篇文章主要介紹了python函式的萬能引數傳參詳解,文中通過示例 介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下 我們通過乙個簡單的事例來展示一下函式的萬能引數,我們先寫乙個最簡單的函式 def test args,kwargs print args,kwargs...