你知道C語言中函數調用和嵌套嗎?函數必學模塊,你不得不知!

2021-01-10 騰訊網

一、函數調用

什麼是函數調用呢?通常在C語言中,一個完整的項目程序是不可能在一個函數中實現所有的功能。而是由若干功能不同的函數來實現,並且函數之間會存在互相調用的情況。

當然了,也不是說就一定要把函數的功能模塊都分開來寫,但是如果你寫成了下面這個樣子:

我估計以後你的項目經理肯定會對你好(ba)言(dao)相(xiang)勸(xiang)的。

二、函數的調用方式

函數是C語言的基本組成元素,如果你要想實現函數的功能,那麼你就必須學會正確調用函數。調用的語法格式如下:

從上面的語法格式可以看出,當我們調用一個函數時,需要明確函數名和實參列表。實參列表中的參數可以是常量、變量、表達式或者空,並且各參數之間要使用英文逗號分隔開來。

根據函數在程序中出現的位置,有下列三種函數調用方式:

1、將函數作為表達式調用

將函數作為表達式調用時,函數的返回值參與表達式的運算,此時要求函數必須有返回值。示例代碼如下所示:

2、將函數作為語句調用

函數以語句的形式出現時,可以將函數作為一條語句進行調用。示例代碼如下所示:

3、將函數作為實參調用

將函數作為另一個函數的實參時,要求該函數有返回值。示例代碼如下所示:

在上面的語句中,將函數max()的返回值作為printf()函數的實參來使用。

三、嵌套調用

在C語言中,函數的定義是獨立的,也就是說,一個函數不能定義在另一個函數內部。

但在調用函數時,可以在一個函數中調用另一個函數,這就是函數的嵌套調用。接下來我們通過一個案例來演示函數的嵌套調用。

案例一:

運行結果:

在這個案例中,main()函數中調用了 max4()函數,max4()函數中又調用了max2()函數。

為了讓大家能夠更好地理解這個程序執行的流程,我們通過一張圖來描述:

這張圖展示了程序中含有三層函數調用嵌套的情形,總共分為9個步驟,具體如下:

(1) 執行main()函數的開頭部分;

(2) 遇到函數調用語句,調用max4()函數,流程轉向max4()函數入口;

(3) 執行max4()函數的開頭部分;

(4) 遇到函數調用語句,調用max2()函數,流程轉向max2()函數入口;

(5) 執行max2()函數,如果再無其他嵌套的函數,則完成max2()函數的全部操作;

(6) 返回到max2()函數中調用max4函數的位置;

(7) 繼續執行max4()函數中尚未執行的部分,直到max4()函數結束;

(8) 返回main()函數中調用max4()函數的位置;

(9) 繼續執行main()函數的剩餘部分直到結束。

& 多學一招:函數調用時最多可以嵌套多少層?

大家肯定會問:「既然函數嵌套調用和普通的調用看上去沒什麼區別,那是不是可以進行無限層的函數嵌套調用呢?」

很遺憾,函數可以嵌套調用多少層是由程序運行時一個名為「棧」的數據結構決定的。

一般而言,Windows上程序的默認棧大小大約為8KB,每一次函數調用至少佔用8個字節,因此粗略計算下,函數調用只能嵌套大約一千層,如果嵌套調用的函數裡包含許多變量和參數,實際值要遠遠小於這個數目。

當然,單純手動書寫代碼寫出一千層嵌套函數調用基本是不可能的,但是一種名為「遞歸」的方法可以輕鬆達到這個上限。

四、遞歸調用

在數學運算中,會遇到計算多個連續自然數之間的和的情況。

例如要計算1~n之間自然數之和,就需要先計算1加2的結果,用這個結果加3再得到一個結果,用新得到的結果加4,以此類推,直到用1~(n-1)之間所有數的和加n。

在程序開發中,要想完成上述功能,就需要使用函數的遞歸調用,所謂的遞歸調用就是函數內部調用自身的過程。

需要注意的是,遞歸必須要求有結束條件,不然就會陷入無限遞歸的狀態,永遠無法結束調用。接下來通過一個計算自然數之和的案例來學習遞歸調用。

案例二:

運行結果:

案例二中,我們定義了一個getsum()函數用於計算1~n之間自然數之和。

案例中的第9行代碼相當於在getsum()函數的內部調用了自身,這就是函數的遞歸,整個遞歸過程在n==1時結束。

由於函數的遞歸調用過程很複雜,接下來通過一個圖例來分析整個調用過程。

這張圖中描述了遞歸調用的過程,整個遞歸過程中getsum()函數被調用了4次,每次調用時,n的值都會遞減。

當n的值為1時,所有遞歸調用的函數都會以相反的順序相繼結束,所有的返回值會進行累加,最終得到的結果為10。

相關焦點

  • C語言函數的調用 - 百度經驗
    在一個程序的編寫過程中,隨著代碼量的增加,如果把所有的語句都寫到 main 函數中,一方面程序會顯得的比較亂,另外一個方面,當同一個功能需要在不同地方執行時,我們就得再重複寫一遍相同的語句。此時,如果把一些零碎的功能單獨 寫成一個函數,在需要它們時只需進行一些簡單的函數調用,這樣既有助於程序結構的清晰條理,又可以避免大塊的代碼重複。
  • Python使用ctypes模塊調用DLL函數之C語言數組與numpy數組傳遞
    在Python語言中,可以使用ctypes模塊調用其它如C++語言編寫的動態連結庫DLL文件中的函數,在提高軟體運行效率的同時,也可以充分利用目前市面上各種第三方的DLL庫函數,以擴充Python軟體的功能及應用領域,減少重複編寫代碼、重複造輪子的工作量,這也充分體現了Python語言作為一種膠水語言所特有的優勢
  • Python使用ctypes模塊調用DLL函數之複數數組的參數傳遞
    這兒就涉及到了如何將C語言中的複數數組(Complex array)類型與Python中的數據類型進行交互的問題。在Python語言中,可以使用ctypes模塊調用其它如C++語言編寫的動態連結庫DLL文件中的函數,前面多篇文章中已經講了傳遞數值/指針/字符串參數、傳遞結構體參數、傳遞普通數組類型的例子,大家可以回看一下,這樣可以更好的理解本次要講的內容。
  • C語言中的main函數參數,你了解嗎?
    小豆丁:今天我才發現,C語言中main函數還有參數,可是我不知道這個參數表示的是什麼含義,也不知道怎麼用。老張:就這點問題?小豆丁:嗯吶,我沒研究明白,好沮喪...老張:這個問題不難,別放棄哈,我教你!
  • 第五篇:C語言中有關函數的相關知識點梳理
    函數是C語言中,組織程序的最基本的結構單元。我們最初學習C語言的第一個程序就是寫在主函數main()裡面的。在學習函數具體應用之前,我們只認識一個主函數,所有的代碼都必須寫在主函數裡面。01理解「函數」在C語言中,除了主函數、系統函數,還可以根據需要定製函數。
  • C語言中的main()函數可以有好幾種類型,為何都能做入口函數呢?
    而C語言沒有重載語法,為什麼在C語言程序中,可以有不同類型的 main() 函數呢?為什麼在C語言程序中,可以有不同類型的 main() 函數呢?C語言程序支持多種類型 main() 函數,其實和支持可變參數函數是類似的。
  • C語言——用函數實現模塊化程序設計
    通過前幾章的學習,我們已經能夠編寫一些簡單的C程序,但想要功能多規模大,將所有的程序代碼都寫在一個主函中,就會使主函數變得複雜,難以理解,頭緒不清,使閱讀和維護程序變得困難。此外有時候程序中要多次實現某一功能(例如列印每一頁的頁頭),就需要多次重複編寫實現此功能的程序代碼,這使程序冗長、不精練。因此,人們自然會想到採用「組裝」的辦法來簡化程序設計的過程。
  • C語言中函數的形參與實參是什麼?
    函數的參數分為形參和實參兩種形參出現:1、在函數定義中,在整個函數體內都可以使用,離開該函數則不能使用。2、實參出現在主調函數中,進入被調函數後,實參變量也不能使用。數據傳送是形參和實參的主要功能。在發生函數調用時,主調函數把實參的值傳送給被調函數的形參從而實現主調函數向被調函數的數據傳送。函數的形參和實參具有以下特點:1. 形參變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。
  • C語言陷阱與技巧第15節,為什麼每調用一次函數,就需要一次if判斷...
    在C語言程序開發中,調用一個有返回值的函數時,一般要對函數的返回值做判斷,以確定函數是否按照預期執行。如果被調用函數沒有按照預期執行,最好加上相應的錯誤處理代碼,否則最終編譯得到的C語言程序穩定性就不夠好,遇到一點點意外,可能就不會正常工作了。沒有判斷C語言函數的返回值,會有什麼問題?
  • C語言編程:以實例教你學指向函數的指針
    指針是C語言的精髓,對於初學者來講,指針是C語言語法學習中比較難的知識點,而這裡面指向函數的指針更是不太容易理解。下面給大家講下怎樣學習理解C語言中指向函數的指針及編程方法和使用例子。注意:這是一篇關於C語言編程的基礎語法內容,C語言大神請繞過。
  • python測試函數模塊unittest
    1.測試函數在編寫完代碼後進行對代碼測試是否有錯誤2.pytho標準庫中的模塊unittest為代碼測試工具例如:name_function.py 模塊名def get_formatted_name(first, last): full_name = first + ' ' + last
  • 你有沒有想過,C語言 main 函數到底為啥這麼寫?
    但凡是學過C語言的人,都知道要先寫main函數,然而很多時候我們看到的main函數卻各有差異,這究竟是為啥?哪種是對的呢?今天我們就來聊聊main函數。那麼main函數一共有多少個版本呢?不過在C89標準中其實是可以的,由於沒有聲明返回類型,所以才會返回默認值int。2、void main()初學者經常會使用的形式,但是並不知道來源在哪,在C89/C99/C11等文檔中都沒有提到這種形式的痕跡。這種寫法的返回值是void,沒有參數。
  • excel函數公式大全之利用SUM函數IF函數的嵌套把成績劃為三個等級
    excel函數公式大全之利用SUM函數和IF函數的嵌套把學生成績劃為三個等級。excel函數與公式在工作中使用非常的頻繁,會不會使用公式直接決定了我們的工作效率,今天我們來學習一下提高我們工作效率的函數SUM函數和IF函數。
  • 很多C語言初學者都非常好奇的問題,怎樣定義可以可變參數函數?
    foo(),它可以接收類似於 printf() 的函數,並且將 fmt 中的 s 解析為字符串,d 解析為整數,c 解析為字符,因此編譯並執行這段C語言代碼,可得到如下輸出:# gcc t.c# ./a.outstring helloint 12char m通過這段實例,可以看出使用C語言定義可變參數函數並不複雜,在處理可變參數時,只需先調用 va_start() 將參數序列加載到 va_list 結構的變量中,然後調用 va_arg() 依次解析。
  • 解讀Python函數閉包的概念及作用域
    在前面的內容中,我們討論了全局變量和局部變量的作用域,也討論了嵌套函數的作用域,並了解了局部變量或嵌套函數僅限於在函數體內使用。但在一些情況下,可以將函數內部的嵌套函數引入到全局環境中使用,Python將引入到全局環境中使用的嵌套函數及其環境變量構建成一個封閉的包,該包內的環境變量不受外部環境的影響,這就是我們將要討論的閉包。前面我們了解了嵌套函數的作用域僅限於其父函數體內,如果在父函數體外調用其嵌套的函數,就會超出嵌套函數的作用域。
  • C語言陷阱與技巧第2節,使用inline函數可以提升程序效率,但是讓...
    打開 Linux 內核原始碼,會發現內核在定義C語言函數時,有很多都帶有 「inline」關鍵字,請看下圖,那麼這個關鍵字有什麼作用呢?inline 關鍵字的作用在C語言程序開發中,inline 一般用於定義函數,inline 函數也被稱作「內聯函數」,C99 和 GNU C 均支持內聯函數。那麼在C語言中,內聯函數和普通函數有什麼不同呢?
  • 大學生計算機二級考試C語言中的函數入門詳解
    今天這次課程我們從基礎的函數講起,教你輕鬆入門C語言。算法是什麼?什麼是算法,這個就有點像我們學習數學的時候的計算了。比如你在排列組合中需要計算5!,但是,你並不知道這個5!是什麼意思和含義,那麼你將計算不出來。而如果我告訴你5!表示5的階乘,其計算方法就是從5開始一直乘到1就是最後的計算結果,那麼你就能計算出來5!了。
  • C語言陷阱與技巧第8節,輸出適當的信息,有利於定位錯誤和異常代碼
    把複雜的任務拆分成簡單的子模塊在C語言程序開發中,程式設計師常常會把一個複雜的任務拆分成若干個較為簡單的子模塊,這些子模塊可以看做是複雜任務的各個組成部分。因此,程式設計師將子模塊逐個完成後,就可以將其像「積木」一樣搭建起來,進而解決複雜任務。
  • ARM中ADS環境下C語言和彙編語言混合編程及示例
    彙編語言是和CPU的指令集緊密相連的,作為涉及底層的嵌入式系統開發,熟練對應彙編語言的使用也是必須的。這裡主要討論C和彙編的混合編程,包括相互之間的函數調用。下面分四種情況來進行討論,不涉及C++語言。
  • 第55p,閉包函數,函數知識的綜合運用
    大家好,我是楊數Tos,這是《從零基礎到大神》系列課程的第55篇文章,第三階段的課程:Python進階知識:Python進階知識:詳細講解Python中的函數(八)====> 函數的嵌套調用之閉包函數。