【C語言】詳解函數(上)(庖丁解牛版)

文章目錄

  • 1. 前言
  • 2. 函數的概念
  • 3.庫函數
    • 3.1 標準庫和頭文件
    • 3.2 庫函數的使用
      • 3.2.1 頭文件的包含
      • 3.2.2 實踐
  • 4. 自定義函數
    • 4.1 自定義函數的語法形式
    • 4.2 函數的舉例
  • 5. 形參和實參
    • 5.1 實參
    • 5.2 形參
    • 5.3 實參和形參的關系
  • 6. return 語句
  • 6. 總結

1. 前言

一講到函數這塊,相信有很多初學者都避而不及。開個玩笑說,你是否聽到函數身體就止不住的顫抖,冷汗直流,必須得來幾瓶匯源腎寶才能勉強繼續學下去。😰😰😰

不過沒關系,相信你看完這個文章之后不會再懼怕函數,甚至可能會愛上使用它。

那么話不多說,讓我們一起去揭開函數這個神秘的面紗吧!😎😎??

2. 函數的概念

古人有云:知己知彼,才能百戰不殆。學習也是如此,當我們面對一個新的知識時,我們得先對這個新事物有個整體的認知,在此基礎上繼續挖掘更深層次的知識,就事半功倍了。

一說到函數,相信大家就想到了初中那段剛接觸到函數的時光,你是否被它折磨的痛不欲生了呢?不過沒有關系,本文會帶你駛向勝利的彼岸。比如:一次函數y=kx+b 、二次函數y=ax2+bx+c,根據函數的映射關系,我們就可以根據自變量(x)的值從而求得因變量(y)。

其實在C語言中也引入了函數(function)這一概念,有些地方也將它翻譯成:子程序,我認為子程序的翻譯更加準確一些。也就是說,函數其實就是一段子程序

那可能有的讀者就會問了,子程序是什么,難道還會有個母函數?

所謂的子程序就是,總的項目程序代碼中的一部分,它能夠完成某一項特定的任務,并且這段代碼有特許的寫法和調用方式。 當然,目前你可以簡單的理解為程序代碼的一部分。相信你看文本后,再回頭思考這個問題時,就會有很深的感悟了。

既然講到了C語言程序這個概念,就再跟大家聊聊什么是程序?

  • 從目的角度理解的話,程序就是程序為了實現某種目的作用于現實生活而編程出來的可執行文件。
  • 從程序本身來理解的話,程序就是由無數個小的函數組合而成,也可以說:一個大的計算任務可以分解成若干個較小的函數(每個函數都對應這一個小的任務)完成。同時一個函數如果能完成某一項特定任務的話,那么這個也是可以重復被使用了,程序員就無需打那么多重復的代碼,大大提高了編程的效率。

在C語言中我們一般會見到兩類函數:

  • 庫函數
  • 自定義函數

在這里我們先從較為簡單庫函數講起。

3.庫函數

說到庫函數,一定就離不開C語言中的標準庫和頭文件。

3.1 標準庫和頭文件

C語言標準中規定了C語言的各種語法規則,C語言本身并不提供庫函數,C語?的國際標準ANSI C規定了?些常?的函數的標準,被稱為標準庫。C語言那到底是誰給我們提供呢?制作編譯器的廠商們。這些廠商們拿著ANSI提供的C語言標準制定了一系列函數的實現。這些函數就被稱為庫函數

總而言之,標準庫就是一個國際組織制定的標準,在里面存放著編譯器廠商是實現的庫函數。

其實,我們在日常編程中幾乎都用到了庫函數,比如printfscanf這些都是庫函數,庫函數也是函數,只不過是別人已經幫我們實現好了,我們只需要直接拿出來用就行了。

各種編譯器的標準庫提供了一系列的庫函數,這些庫函數根據功能的劃分,都在不同的頭文件中進行了聲明(也就是說,我們在使用這些庫函數時,得先包含對應的頭文件)。

庫函數相關頭文件鏈接:https://zh.cppreference.com/w/c/header

里面的函數多種多樣,不需要大家一次性學完,等需要用到的時候,再去查就可以了。

3.2 庫函數的使用

庫函數的學習和查找工具有很多,以下是我推薦給大家的:
C/C++官?的鏈接:https://zh.cppreference.com/w/c/header
cplusplus.com:https://cplusplus.com/

舉例:sqrt

double sqrt(double x);
//sqrt是函數名
//x 是函數的參數,表示調用sqrt函數時需要傳遞一個double類型的值
//double 是返回值類型 —— 表示函數計算的結果是一個double類型的值

以下截圖是來自:cplusplus網站
sqrt函數

3.2.1 頭文件的包含

在前面我有提及過,在我們使用庫函數,要先包含一個頭文件。因為庫函數是在標準庫中對應的頭文件中聲明的,所以使用庫函數時請務必包含頭文件。

這就好比,你去借別人的東西,不包含頭文件的情況,就比做你直接就拿別人的東西去用了,也沒詢問過別人的意見,這個就是一個很沒有禮貌的行為。而包含了頭文件之后,就比做你已經再征得別人的同意后才使用的,這就是一個有禮貌行為的體現。

3.2.2 實踐

講了這么多了,是時候動手寫個代碼,給大家展示一下用法:

#include<stdio.h>
#include<math.h> //sqrt函數被聲明在這個頭文件里,得先打聲招呼int main()
{double x = 16.0;double r = sqrt(x);printf("%lf\n",r);return 0;
}

大家下來可以自己測試一下結果!

4. 自定義函數

了解了庫函數之后,我們的關注度應該放在自定義函數上,自定義函數其實更加重要,也能給程序員寫代碼更多的創造性。

4.1 自定義函數的語法形式

其實自定義函數和庫函數一樣,形式如下:

ret_num fun_name(形式參數)
{...
}
名稱意義
ret_num是函數的返回值類型
fun_name是函數名
()里面放的內容是形式參數
{…}括里面的內容是函數體(函數的主要內容)

函數工廠
我們可以把函數想象成一座小型的工廠,工廠通過輸入進來的原材料,經過加工才能身邊生產出產品。那函數也是一樣的,函數一般會給它輸入一些值(可以是0個,也可以是多個),經過函數內部的計算,得出最終的計算結果。

為此,我再次寫一下,函數創建語法時,各個英文單詞所代表的具體含義。請大家對照著理解,

  • ret_type 是?來表?函數計算結果的類型,有時候返回類型可以是 void ,表?什么都不返回
  • fun_name 是為了?便使?函數;就像?的名字?樣,有了名字?便稱呼,函數有了名字?便調?,所以函數名盡量要根據函數的功能起的有意義。
  • 函數的參數就相當于,工廠中送進去的原材料,函數的參數也可以是 void ,明確表?函數沒有參數。如果有參數,要交代清楚參數的類型和名字,以及參數個數。
  • {}括起來的部分被稱為函數體,函數體就是完成計算的過程。

4.2 函數的舉例

舉個例子:
寫一個加法函數,完成對兩個整型變量的加法操作。

在我們沒學過函數之前,你可能會這么寫:

#include<stdio.h>
int main()
{int a = 0;int b = 0;scanf("%d %d",&a,&b);int ret = a + b;printf("ret = %d\n", ret);return 0;
}

這是你學過函數之后寫的代碼:

#include<stdio.h>
int Add(int x, int y) //x,y就是形式參數
{int sum = 0;sum = x + y;return sum;
}int main()
{int a = 0;int b = 0;scanf("%d %d",&a,&b);int ret = Add(a, b);printf("ret = %d\n", ret);return 0;
}

自定義函數舉例

不過上述的Add函數的寫法還可以再簡化

int Add(int x, int y)
{return x + y;
}

上?只是?個例?,未來我們是根據實際需要來設計函數,函數名、參數、返回類型都是可以靈活變化的。

5. 形參和實參

在函數的使用過程中,把函數的參數分為,實參和形參。
在看看我們之前舉例的代碼:

#include<stdio.h>
int Add(int x, int y) //x,y就是形式參數
{int sum = 0;sum = x + y;return sum;
}int main()
{int a = 0;int b = 0;scanf("%d %d",&a,&b);int ret = Add(a, b);printf("ret = %d\n", ret);return 0;
}

5.1 實參

在上面代碼中第2~7行是Add函數的定義,有了函數之后,再調用第14行的Add函數。
我們把調用Add函數時,傳遞給Add函數的參數a和b,稱為實際參數,簡稱實參

實際參數就是真實給函數傳遞的值。

可以理解為實參就是給這個函數的原材料。

或者,我再舉一個生動的例子。就比如說,我們的手機沒電時,需要充電,第一步就是將充電器插入到電插座中,第二步就是將充電頭插入自己手機的充電口中。這兩步的插入目的就是給手機充電,就好比我們給函數傳遞實參一樣。函數需要這么一個介質,才能發揮出它應有的功能。

5.2 形參

在上面代碼中,第二行定義函數時,在函數名Add后的括號中寫的xy,稱為形式參數,簡稱形參

為什么會叫形式參數呢?實際上,如何只是定義了Add函數而不去調用的話,Add函數的參數x和y只是形式上存在的,它們是不會向內存申請空間的,不會真實存在的,所以叫形式參數。形式參數只有在函數被調用的過程中,才會向內存中申請空間,這個過程就叫做形式參數的實例化

5.3 實參和形參的關系

形式參數和實際參數,它們的名字中都有參數二字,那它們中間有什么關系嗎?

請大家務必記住這句話:

形參是實參的一份臨時拷貝

為什么這么說呢?
下面我就通過調試辦法來觀察參數的變化:
形參和實參的關系
在調試的時候,我們發現x和y的確是得到了a和b的值,但是x和y的地址與a和b的地址是不一樣的,所以我們就可以理解為形參是實參的一份臨時拷貝

6. return 語句

return作為C語言中的關鍵字,在自定義函數中時常出現,這里就講一下return語句使用的注意事項:

  • return后面可以是個數值,也可以是個表達式,如果是表達式則先執行表達式,再返回表達式的結果。
  • return后邊也可以什么都沒有,直接寫return;這種寫法適合函數返回值類型是void的情況。
  • return返回的值和函數返回值的類型不一致,系統會自動將返回的值隱式轉換為函數的返回類型。
  • return語句執行后,函數就徹底返回了,后邊的代碼就不再執行了。
  • 如果函數中存在if等分支語句時,則要保證每種情況下都有return返回,否則就會出現編譯錯誤。

為了方便大家的理解,我會給出幾段代碼,分別說明一下,遵守這些規則的好處以及不遵守這些規則所帶來一些意想不到的"效果"

注意事項1:return后面可以是個數值,也可以是個表達式,如果是表達式則先執行表達式,再返回表達式的結果。

//我們可以這樣寫
int Add(int x, int y)
{return x+y; //這個return語句后面是一個表達式
}int main()
{int a = 0;int b = 0;scanf("%d %d",&a,&b);int ret = Add(a, b);printf("ret = %d\n", ret);return 0;
}

return語句后面是一個表達式

注意事項2:return后邊也可以什么都沒有,直接寫return;這種寫法適合函數返回值類型是void的情況。

void Print()
{printf("***********\n");printf("***********\n");printf("***********\n");printf("***********\n");return;//這個其實可寫可不寫
}int main()
{Print();return 0;
}

return語句所處的函數的返回值為void的情況
注意事項3:return返回的值和函數返回值的類型不一致,系統會自動將返回的值隱式轉換為函數的返回類型。

3
這里編譯器會報出個警告:
warning
但是我們這樣改進的話就不會出現了:
3
注意事項4/5:return語句執行后,函數就徹底返回了,后邊的代碼就不再執行了。
4
可以看到hehehehe并沒有被打印處理來,也就說明了,當函數體執行到return語句之后,后面的語句就不再被執行。

6. 總結

本文講解了什么是標準庫、庫函數,以及介紹了函數的定義,函數的調用。還仔細地剖析了自定義函數的語法,形式參數和實際參數及其它們之間的關系,return語句。

本章內容有點豐富,希望讀者們下來好好理解。🥇????

學習很難,但堅持一定很酷!!!😎😎😎

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/22870.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/22870.shtml
英文地址,請注明出處:http://en.pswp.cn/web/22870.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

棧排序00

題目鏈接 棧排序 題目描述 注意點 對棧進行排序使最小元素位于棧頂最多只能使用一個其他的臨時棧存放數據不得將元素復制到別的數據結構&#xff08;如數組&#xff09;中棧中的元素數目在[0, 5000]范圍內 解答思路 本題是要實現一個小頂堆&#xff0c;可以直接使用Priori…

上位機圖像處理和嵌入式模塊部署(f407 mcu中的udp server開發)

【 聲明&#xff1a;版權所有&#xff0c;歡迎轉載&#xff0c;請勿用于商業用途。 聯系信箱&#xff1a;feixiaoxing 163.com】 既然lwip已經port到407上面了&#xff0c;接下來其實就可以做一些測試了。本身lwip支持tcp、udp&#xff0c;也支持client和server&#xff0c;既然…

【數據分享】中國第三產業統計年鑒(1991-2022)

大家好&#xff01;今天我要向大家介紹一份重要的中國第三產業統計數據資源——《中國第三產業統計年鑒》。這份年鑒涵蓋了從1991年到2022年中國第三產業統計全面數據&#xff0c;并提供限時免費下載。&#xff08;無需分享朋友圈即可獲取&#xff09; 數據介紹 每年的《中國…

LeetCode.55 跳躍游戲

LeetCode.55 跳躍游戲 題目描述解題思路錯誤的解題思路解題思路 代碼 題目描述 解題思路 錯誤的解題思路 我一開始的思路是累加可跳范圍內的最大值sum&#xff0c;如果最終sum > nums.size()那么就返回true&#xff0c;這種思路是錯誤的&#xff0c;因為在你選擇最大值的…

2004NOIP普及組真題 3. FBI樹

線上OJ 地址&#xff1a; [04NOIP普及組] FBI樹 本題的意思是&#xff1a;給定一個 01字符串 &#xff08;對應一棵完全二叉樹的最后一層葉子節點&#xff09;&#xff0c;將樹的每一個節點的值用字母“F、B、I”表示。規則&#xff08;如下圖所示&#xff09;為&#xff1a; 1…

Spring AI 第二講 之 Chat Model API 第二節Ollama Chat

通過 Ollama&#xff0c;您可以在本地運行各種大型語言模型 (LLM)&#xff0c;并從中生成文本。Spring AI 通過 OllamaChatModel 支持 Ollama 文本生成。 先決條件 首先需要在本地計算機上運行 Ollama。請參閱官方 Ollama 項目 README&#xff0c;開始在本地計算機上運行模型…

curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL

source ~/.bash_profile flutter clean Command exited with code 128: git fetch --tags Standard error: 錯誤&#xff1a;RPC 失敗。curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL (err 8) 錯誤&#xff1a;預期仍然需要 2737 個字節的正文 fetch-pack: unexpec…

GPT革命:AI如何重塑我們的未來!

GPT革命&#xff1a;AI如何重塑我們的未來&#xff01; &#x1f604;生命不息&#xff0c;寫作不止 &#x1f525; 繼續踏上學習之路&#xff0c;學之分享筆記 &#x1f44a; 總有一天我也能像各位大佬一樣 &#x1f3c6; 博客首頁 怒放吧德德 To記錄領地 &#x1f31d;分享…

普通人也能弄的 16 個AI搞錢副業,門檻低,易上手!

大家好&#xff0c;我是靈魂畫師向陽 本期給大家分享的是利用AI 做副業的一些方法&#xff0c;大家可以挑選適合自己的賽道去搞錢 現在是人工智能時代&#xff0c;利用好AI 工具&#xff0c;可以降低普通人做副業的門檻&#xff0c;同時也能提高工作效率&#xff0c; 因此AI …

【微機原理與匯編語言】循環程序設計

一、實驗目的 1.熟練掌握8086/8088常用匯編指令的使用方法 2.熟練掌握循環結構程序編程技巧 3.熟練掌握匯編語言程序運行調試方法 二、實驗要求 認真分析實驗題目&#xff0c;設計程序流程圖&#xff0c;獨立完成代碼編寫及運行調試。 三、實驗題目 給出不大于255的十個…

圖片裁剪與上傳處理方案 —— 基于阿里云 OSS 處理用戶資料

目錄 01: 通用組件&#xff1a;input 構建方案分析 02: 通用組件&#xff1a;input 構建方案 03: 構建用戶資料基礎樣式 04: 用戶基本資料修改方案 05: 處理不保存時的同步問題 06: 頭像修改方案流程分析 07: 通用組件&#xff1a;Dialog 構建方案分析 08: 通用組件&…

計算機組成原理·考點知識點整理

根據往年考試題&#xff0c;對考點和知識點的一個整理。 校驗編碼 碼距 一種編碼的最小碼距&#xff0c;其實就是指這種編碼的碼距。碼距有兩種定義&#xff1a; 碼距所描述的對象含義 2 2 2 個特定的碼其二進制表示中不同位的個數一種編碼這種編碼中任意 2 2 2 個合法編碼的…

【linux進程控制(三)】進程程序替換--如何自己實現一個bash解釋器?

&#x1f493;博主CSDN主頁:杭電碼農-NEO&#x1f493; ? ?專欄分類:Linux從入門到精通? ? &#x1f69a;代碼倉庫:NEO的學習日記&#x1f69a; ? &#x1f339;關注我&#x1faf5;帶你學更多操作系統知識 ? &#x1f51d;&#x1f51d; 進程程序替換 1. 前言2. exec…

【JMeter接口自動化】第8講 Fiddler抓包Jmeter

1&#xff09;配置好Fiddler 設置Fiddler-Tools-Options-HTTPS 設置Fiddler-Tools-Options-Connections&#xff0c;設置端口為8888 2&#xff09;查看IP 在CMD中輸入ipconfig 查看IP地址 3&#xff09;配置Jmeter Http請求——基本&#xff0c;設置Http請求&#xff0c;使用…

輕量管理內核復雜級別的項目

在嵌入式開發中&#xff0c;管理大型項目&#xff08;例如Linux內核&#xff09;往往是一個復雜的過程。常規的版本控制系統如Git在處理小型項目時非常高效&#xff0c;但面對龐大的代碼庫時可能會顯得笨重且占用大量存儲空間。本文將介紹幾種輕量級的方法來管理內核級別的項目…

Python 快速入門

1. 語言基礎 1.1 數據類型與變量 Python 是一門動態類型語言&#xff0c;這意味著你不需要顯式聲明變量的類型。Python 解釋器會根據你賦予變量的值自動推斷其類型。這使得 Python 代碼簡潔易懂&#xff0c;但同時也需要注意一些潛在的問題。 1.1.1 Python 數據類型概述 Py…

408鏈表的創建和初始化

首先第一個頭文件&#xff0c;定義結構體類型 typedef struct LNode {int data;struct LNode* next; }LNode,*LinkList; //可能作為第一次寫c語言的小伙伴看不懂這一段typedef是如何定義的 //基本的解釋如下所示 //typedef struct LNode LNode; //typedef struct LNode* LinkL…

apex代碼發送郵件時進行抄送

在 Salesforce 中使用 Apex 代碼發送電子郵件時&#xff0c;可以通過 ccAddresses 屬性來添加抄送&#xff08;CC&#xff09;收件人。以下是一個示例代碼&#xff0c;展示了如何使用 Messaging.SingleEmailMessage 類來發送帶有抄送的電子郵件。 示例代碼 public class Emai…

北航數據結構與程序設計第四次作業選填題復習

首先都是線性的&#xff0c;線性包括順序和鏈式&#xff0c;棧和隊都可以用兩種方式實現。棧只能存于棧頂取于棧頂&#xff0c;隊列先進先出&#xff0c;因此存取點是固定的。 函數棧幀創建原理 畫圖即可。 A.顯然不行&#xff0c;5如果第一個出來說明5是最后一個進的&#xf…

Lambda表達式與函數式工具在Python中的應用詳解

目錄 一、引言 二、Lambda表達式 Lambda表達式的定義 Lambda表達式的使用場景 Lambda表達式的示例 三、函數式工具 map()函數 filter()函數 reduce()函數 itertools模塊 functools模塊 四、Lambda表達式與函數式工具的結合使用 五、Lambda表達式與函數式工具的注意…