C語言教程(十):C 語言函數詳解

一、引言

????????在 C 語言中,函數是一組執行特定任務的代碼塊。通過將復雜的程序邏輯劃分為多個函數,不僅能提高代碼的可讀性、可維護性,還便于代碼的復用。無論是簡單的數學計算,還是復雜的系統操作,函數都發揮著核心作用。掌握函數的使用方法,是提升 C 語言編程能力的重要環節。

二、函數的定義

? 2.1 基本語法:

返回值類型 函數名(參數列表) {

????// 函數體

????語句;

????return 返回值;

}

返回值類型:指定函數執行完成后返回的數據類型,若函數無需返回值,使用void。

函數名:遵循標識符命名規則,用于唯一標識函數。

參數列表:可以包含零個或多個參數聲明,參數之間用逗號分隔,若沒有參數,使用void或留空。

函數體:由一系列語句組成,是函數執行的具體邏輯。

return 語句:用于終止函數執行,并將返回值傳遞給調用者。若無返回值,return語句可省略。

? 2.2 示例:

????????計算兩個整數之和的函數:

int add(int a, int b) {int sum = a + b;return sum;
}

????????此函數add接收兩個int類型參數ab,計算它們的和并返回。

三、函數的聲明

? 3.1 聲明的作用:

????????函數聲明告知編譯器函數的名稱、返回值類型和參數類型,使編譯器在編譯時能夠對函數調用進行合法性檢查。函數聲明通常放在調用函數的代碼之前。

??3.2 語法:

返回值類型 函數名(參數列表);

????????聲明與定義類似,但函數聲明末尾需加分號,且函數體部分省略。例如,上述add函數的聲明為:

int add(int a, int b);

? 3.3 聲明的位置:

????????全局聲明:在所有函數外部聲明,作用域為整個源文件,可被文件內所有函數調用。

????????局部聲明:在函數內部聲明,作用域僅限于該函數內部。一般用于在函數內部調用其他自定義函數時,確保編譯器知曉被調用函數的信息。

四、函數的調用

? 4.1 調用方式:

????????通過函數名后跟一對圓括號來調用函數,若函數有參數,在括號內傳入相應參數值。例如調用上述add函數:

int result = add(3, 5);

????????此語句將調用add函數,傳入參數 3 5,函數返回值賦給result變量。

??4.2 函數調用過程:

????????參數傳遞:將實際參數的值復制給函數定義中的形式參數。

????????執行函數體:按照函數體中的語句順序執行代碼。

????????返回值處理:遇到return語句時,函數終止執行,將返回值傳遞給調用處,繼續執行調用函數后的代碼。

五、函數參數

? 5.1 形式參數與實際參數:

????????形式參數:函數定義中參數列表里的參數,在函數被調用前并不占用實際內存空間,只有在函數調用時才被分配內存并接收實際參數的值。

????????實際參數:函數調用時傳遞給函數的表達式、變量或常量。例如在add(3, 5)中,3 和 5 就是實際參數。

??5.2 參數傳遞方式:

????????值傳遞:C 語言默認的參數傳遞方式。實際參數的值被復制到形式參數中,函數內部對形式參數的修改不會影響實際參數。例如:

void modify(int num) {num = num * 2;
}
int main() {int value = 5;modify(value);// value 仍為 5,未被修改return 0;
}

????????指針傳遞:通過傳遞變量的地址來實現。函數內部可通過指針修改所指向的實際變量的值。例如:

void modify(int *ptr) {*ptr = *ptr * 2;
}
int main() {int value = 5;modify(&value);// value 變為 10,已被修改return 0;
}

??5.3 可變參數:

????????C 語言允許函數接受可變數量的參數,通過<stdarg.h>頭文件中的宏來實現。例如printf函數就是典型的可變參數函數。

#include <stdarg.h>
#include <stdio.h>
int sum(int count, ...) {va_list args;va_start(args, count);int result = 0;for (int i = 0; i < count; i++) {result += va_arg(args, int);}va_end(args);return result;
}
int main() {int total = sum(3, 1, 2, 3);// total 為 6return 0;
}

????????上述sum函數可接受任意數量的整數參數,并計算它們的和。

六、函數的返回值

? 6.1 返回值類型:

????????函數的返回值類型在函數定義和聲明時指定。返回值類型必須與return語句后表達式的類型兼容。若不兼容,編譯器會進行類型轉換。例如:

double divide(int a, int b) {return (double)a / b;
}

該函數將兩個整數相除,并返回double類型的結果。

??6.2 無返回值函數:

????????若函數無需返回值,使用void作為返回值類型。例如:

void printMessage() {printf("Hello, World!\n");
}

????????此類函數執行完函數體后,直接返回調用處,無需return語句。若使用return,其后不能有返回值表達式。

七、函數指針

? 7.1 定義與使用:

????????函數指針是指向函數的指針變量。通過函數指針可以調用函數,常用于實現回調函數等功能。

// 定義函數指針類型
typedef int (*FuncPtr)(int, int);
int add(int a, int b) {return a + b;
}
int main() {FuncPtr ptr = add;int result = ptr(3, 5);// result 為 8return 0;
}

????????上述代碼中,FuncPtr是一個指向返回值為int,接受兩個int類型參數的函數指針類型。通過FuncPtr定義指針變量ptr,并使其指向add函數,然后通過ptr調用add函數。

??7.2 函數指針作為參數:

????????函數指針可作為其他函數的參數,用于將一個函數的行為傳遞給另一個函數。例如:

int operate(int a, int b, int (*func)(int, int)) {return func(a, b);
}
int add(int a, int b) {return a + b;
}
int subtract(int a, int b) {return a - b;
}
int main() {int result1 = operate(5, 3, add);int result2 = operate(5, 3, subtract);// result1 為 8,result2 為 2return 0;
}

????????operate函數接受兩個整數和一個函數指針作為參數,通過函數指針調用不同的函數進行計算。

八、遞歸函數

? 8.1 遞歸的概念:

????????遞歸函數是指在函數內部調用自身的函數。遞歸通常用于解決可以分解為更小、相似問題的場景。遞歸函數必須有終止條件,否則會導致無限遞歸,最終耗盡系統資源。

??8.2 示例:

????????計算階乘的遞歸函數:

int factorial(int n) {if (n == 0 || n == 1) {return 1;} else {return n * factorial(n - 1);}
}

????????當n01 時,函數返回 1 作為終止條件;否則,通過遞歸調用factorial(n - 1)計算n的階乘。

九、函數的作用域與存儲類

? 9.1 作用域:

????????函數的作用域從函數定義處開始,到文件末尾結束。函數內部定義的變量為局部變量,作用域僅限于函數內部;在函數外部定義的變量為全局變量,作用域為整個源文件。若在函數內部定義了與全局變量同名的局部變量,在函數內部局部變量會覆蓋全局變量。

? 9.2 存儲類:

????????自動存儲類(auto):函數內定義的局部變量默認是自動存儲類,存儲在棧中,函數執行結束時,變量所占用的內存被釋放。

????????靜態存儲類(static):若將局部變量聲明為static,其生命周期會延長至程序結束,且在函數多次調用間保持值不變。靜態局部變量存儲在靜態存儲區。例如:

void increment() {static int count = 0;count++;printf("Count: %d\n", count);
}

????????每次調用increment函數,count的值都會遞增并保留。

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

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

相關文章

力扣面試150題--有效的字母異位詞和字母異位詞分組

Day 24 題目描述 思路 初次思路&#xff1a;如果兩個字符串為異位詞&#xff0c;說明它們長度相同并且字母出現的次數相同&#xff0c;于是有以下做法&#xff1a; 定義一個map&#xff0c;來保存s中每個字符的出現次數處理特殊情況&#xff0c;如果長度不同&#xff0c;直接…

數理邏輯(Mathematical Logic)綜論與跨學科應用

李升偉 整理 數理邏輯&#xff08;Mathematical Logic&#xff09;是現代邏輯學與數學交叉的核心學科&#xff0c;以嚴格的數學方法研究邏輯推理的形式與規律。其發展深刻影響了數學基礎、計算機科學、語言哲學等領域。以下從多個維度綜論數理邏輯&#xff1a; 1. 核心分支 命…

高性能內存kv數據庫Redis(續)

目錄 四.主從同步與對象模型 1.Redis 淘汰策略 2.Redis 如何做到 持久化 2.1 redis為什么要實現持久化 2.2fork進程的寫時復制機制 2.3大Key的影響 2.4redis做持久化的方式 2.5 aof 2.6 rdb 2.7 redis 持久化方式的優缺點 3.redis里面的高可用體現在哪里&#xff1f; 3.1r…

泛型算法——只讀算法(一)

在 C 標準庫中&#xff0c;泛型算法的“只讀算法”指那些 不會改變它們所操作的容器中的元素&#xff0c;僅用于訪問或獲取信息的算法&#xff0c;例如查找、計數、遍歷等操作。 accumulate std::accumulate()是 C 標準庫**numeric**頭文件中提供的算法&#xff0c;用于對序列…

SvelteKit 最新中文文檔教程(21)—— 最佳實踐之圖片

前言 Svelte&#xff0c;一個語法簡潔、入門容易&#xff0c;面向未來的前端框架。 從 Svelte 誕生之初&#xff0c;就備受開發者的喜愛&#xff0c;根據統計&#xff0c;從 2019 年到 2024 年&#xff0c;連續 6 年一直是開發者最感興趣的前端框架 No.1&#xff1a; Svelte …

健康養生:開啟活力生活的密鑰

當我們在健身房看到年逾六旬卻身形矯健的老人&#xff0c;在公園偶遇精神矍鑠、步伐輕快的長者&#xff0c;總會驚嘆于他們的健康狀態。其實&#xff0c;這些都得益于長期堅持科學的養生之道。健康養生并非遙不可及的玄學&#xff0c;而是融入生活細節的智慧。? 在飲食的世界…

Linux信號三部曲:產生機制、處理方式與內核接口

Linux系列 文章目錄 Linux系列前言一、背景知識鋪墊1.1 信號的基本概念1.2 進程對信號的處理 二、信號的產生2.1 前臺進程和后臺進程2.2 鍵盤組合鍵2.3 kill 命令2.4 系統調用2.4.1 signal()接口2.4.2 kill()接口2.4.3 raise()接口2.4.4 abort()接口 總結 前言 Linux中&#x…

win7/win10/macos如何切換DNS,提升網絡穩定性

本篇教程教您如何在Windows10、Windows8.1、Windows7、MacOS操作系統切換DNS&#xff0c;以提升系統的穩定性&#xff0c;獲得更好的操作體驗。 Windows10及Windows8.1 1、右鍵單擊“此計算機”&#xff0c;然后選擇“屬性”。進入Windows系統界面后&#xff0c;選擇左側的“…

移動硬盤突然打不開緊急救援指南:從排查到完整恢復?

突發狀況的典型特征? 當移動硬盤突然打不開時&#xff0c;用戶常會遇到多種異常表現&#xff1a;接入電腦后硬盤指示燈雖亮但無法識別、系統反復提示“設備未連接成功”或彈出“磁盤結構損壞”的警告。部分情況下&#xff0c;資源管理器中的盤符雖可見&#xff0c;但雙擊后顯示…

華為OD機試真題——統計匹配的二元組個數(2025A卷:100分)Java/python/JavaScript/C++/C語言/GO六種最佳實現

2025 A卷 100分 題型 本文涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、測試用例以及綜合分析&#xff1b; 并提供Java、python、JavaScript、C、C語言、GO六種語言的最佳實現方式&#xff01; 2025華為OD真題目錄全流程解析/備考攻略/經驗分享 華為OD機試真題《統計匹配…

半導體制造如何數字化轉型

半導體制造的數字化轉型正通過技術融合與流程重構&#xff0c;推動著這個精密產業的全面革新。全球芯片短缺與工藝復雜度指數級增長的雙重壓力下&#xff0c;頭部企業已構建起四大轉型支柱&#xff1a; 1. 數據中樞重構產線生態 臺積電的「智慧工廠4.0」部署著30萬物聯網傳感器…

[Spark]深入解密Spark SQL源碼:Catalyst框架如何優雅地解析你的SQL

本文內容組織形式 總結具體例子執行語句解析層優化層物理計劃層執行層 猜你喜歡PS 總結 先寫個總結&#xff0c;接下來會分別產出各個部分的源碼解析&#xff0c;Spark SQL主要分為以下五個執行部分。 具體例子 接下來舉個具體的例子來說明 執行語句 SELECT name, age FR…

【數據結構】4.單鏈表實現通訊錄

在上一篇文章我們學會了用單鏈表來實現各種方法&#xff0c;在這一篇文章我們將在單鏈表的基礎上實現通訊錄。 0、準備工作 實現通訊錄之前&#xff0c;我們還需要在單鏈表的基礎上添加2個文件&#xff0c;頭文件Contact.h和源文件Contact.c。Contact.c來實現通訊錄方法的聲明…

【bash】.bashrc

查看當前路徑文件數量 alias file_num"ls -l | grep ^- | wc -l"查看文件大小 alias file_size"du -sh"alias ll alias ll"ls -ltrh"cd的同時執行ll alias cdcdls; function cdls() {builtin cd "$1" && ll }自定義prompt…

微信小程序實戰案例 - 餐館點餐系統 階段 2 – 購物車

階段?2 – 購物車&#xff08;超詳細版&#xff09; 目標 把“加入購物車”做成 全局狀態&#xff0c;任何頁面都能讀寫在本地 持久化&#xff08;關閉小程序后購物車仍在&#xff09;新建 購物車頁&#xff1a;數量增減、總價實時計算、去結算入口打 Git?Tag v2.0?cart 1. …

從紅黑樹到哈希表:原理對比與典型場景應用解析(分布式以及布隆過濾器)

在數據結構的世界里&#xff0c;紅黑樹一直以「自平衡二叉查找樹」的身份備受贊譽。憑借紅黑節點的精妙設計&#xff0c;它能將插入、刪除、查找的時間復雜度穩定控制在 ( log ? n ) (\log n) (logn)&#xff0c;成為處理有序數據的經典方案。然而&#xff0c;當業務場景對「…

游戲報錯?MFC140.dll怎么安裝才能解決問題?提供多種MFC140.dll丟失修復方案

MFC140.dll 是 Microsoft Visual C 2015 運行庫的重要組成部分&#xff0c;許多軟件和游戲依賴它才能正常運行。如果你的電腦提示 "MFC140.dll 丟失" 或 "MFC140.dll 未找到"&#xff0c;說明系統缺少該文件&#xff0c;導致程序無法啟動。本文將詳細介紹 …

《電子類專業:通往科技未來的鑰匙》

一、電子類專業全景概覽 在當今科技飛速發展的時代,電子類專業無疑占據著現代科技體系中基礎與核心的重要地位。從我們日常生活中不可或缺的智能手機、電腦,到推動社會進步的人工智能、大數據技術,再到探索宇宙奧秘的航天航空設備,電子類專業的身影無處不在。它就像一把萬…

Java--批量刪除

前端部分 前端代碼主要負責收集用戶選擇的學生記錄的 id&#xff0c;并將這些 id 發送給后端的 DeleteMoreServlet 進行處理。 批量刪除按鈕綁定點擊事件 $(".deleteMore").on("click",function(){// ... }); 當用戶點擊 “批量刪除” 按鈕時&#xff…

2025年4月份生活有感

今天在5000B培訓的下午&#xff0c;一起入所來的小伙伴&#xff0c;有個申請了深圳大學的博士&#xff0c;已錄取。哎&#xff0c;想起了當年申博時候信心和決心不足&#xff0c;導致后面匆匆的拿了offer去工作。看到同事的選擇還是非常羨慕&#xff0c;想到自己5月份的婚禮&am…