1定義:
在C語言中,函數是一段具有特定功能的獨立代碼塊,它可以接收輸入參數、執行相關操作并返回結果。
2為什么需要函數
(1)代碼復用:避免重復編寫相同功能的代碼, (2)模塊化設計:將復雜程序分成多個小功能模塊,每個函數負責一個獨立任務,使代碼邏輯結構更加清晰。一般一個函數的代碼在50行左右 (3)好處:便于維護和調試(單個函數功能單一,出現問題容易定位和修改,不需要改動整個程序。 (4)提高開發效率:便于多人協同開發時,分工明確,編寫不同函數,最終組合成完整程序。
3、函數的聲明
(1) 基本語法
函數聲明:返回類型 函數名(形參列表);函數首部+分號就是函數聲明,只有函數聲明而沒有函數定義會編譯報錯
函數定義: 在函數聲明的基礎上添加函數體
返回類型 函數名(形參列表) { //函數體 } 只有函數定義而沒有函數聲明可能會編譯警告或出錯(函數聲明可以忽略不寫) 函數定義一般寫在源文件中 .c.cpp
(2)分析語法
1> 返回類型 i. 數組不可以做函數的返回類型(弱化為指針) i.如果函數不需要任何返回值,則返回類型寫為 void i.函數中,主要返回類型不是void,就一定需要用到return(若沒有則有隱藏bug) i.如果返回類型是void,也可以使用return,通常書寫形式為:return;只是用來結束當前函數 i.必須要確保函數全域返回。 2>函數名 i.與變量的命名規則一致(企業要求) i.>在C語言中,函數名也是函數的起始地址,函數名通過printf輸出(十六進制) i.>在C語言中,不允許出現同名函數(c++例外) 3>形參列表 1.>在函數定義或聲明時,函數首部中的函數稱為形參(臨時,調用完成后消失) i.在函數被調用時,其傳遞的參數稱為實參,實參不帶有類型 i.函數參數根據實際情況,可有可無,通常要求形參個數不超過5個。 形參和實參不僅個數和類型一一完全匹配。 多個參數之間需要通過逗號分隔 多個形參,其每個形參需要獨立的類型,不能進行合并 參數分為:入參,出參,出入參 入參:從實參到形參的單向只傳遞(從內存角度看) 出參:能將數據通過參數帶回給函數調用處 函數的參數可以是不固定個數,也可以是可變參數 實參變量名可以和形參不一樣
函數傳參的形式
值傳遞:單向值傳遞
指針傳遞
引用傳遞(C++)
(3)內存布局
棧區,堆區,全局/靜態數據區、文本區、常量區
棧區:局部變量、函數形參
特點:由編譯器自動分配和釋放。遵循"先進后出"原則
堆區:通過malloc等函數動態開辟、Free動態釋放的內存
全局/靜態數據區:存儲全局或靜態數據
文本區:主要針對代碼
常量區:主要存儲代碼
棧區,堆區、數據段(初始化數據段,未初始化數據段)、代碼段
靜態初始化變量只初始化一次,存在全局/靜態數據區
(4)參數調用過程
A.參數壓棧(保存相關數據信息
在函數調用前,先將參數從右到左的順序如棧。先進后出
比如fun(a,b,c);先入棧c,后入棧b,最后入棧a
B.保存現場
保存當前函數的寄存器
C.挑戰到被調函數
開始執行函數體
D.棧幀創建
被調函數先保存調用函數的棧基址,然后在創建自己的基地址,用于定位局部變量和參數
E.執行函數體
F.結果返回
函數中執行return時,將返回值保存在eax中。釋放局部變量的棧空間,恢復調用函數的棧基址和寄存器等。
G.恢復現場
從棧中取出返回值,跳轉回調用函數的下一條指令。
除去返回值
入棧,出棧
代碼如下
#include <stdio.h>
`int main()
{
long long num1 = 0xAAAAAAAA;
long long num2 = 0xBBBBBBBBCCCCCCCC;
long long num3 = 0xDDDDDDDD;
? ? printf("%p, %p, %p\n", num1, num2, num3);
}