日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【C 语言】C 语言 函数 详解 ( 函数本质 | 顺序点 | 可变参数 | 函数调用 | 函数活动记录 | 函数设计 ) [ C语言核心概念 ]

發布時間:2025/6/17 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C 语言】C 语言 函数 详解 ( 函数本质 | 顺序点 | 可变参数 | 函数调用 | 函数活动记录 | 函数设计 ) [ C语言核心概念 ] 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

相關文章鏈接 :
1.【嵌入式開發】C語言 指針數組 多維數組
2.【嵌入式開發】C語言 命令行參數 函數指針 gdb調試
3.【嵌入式開發】C語言 結構體相關 的 函數 指針 數組
4.【嵌入式開發】gcc 學習筆記(一) - 編譯C程序 及 編譯過程
5.【C語言】 C 語言 關鍵字分析 ( 屬性關鍵字 | 常量關鍵字 | 結構體關鍵字 | 聯合體關鍵字 | 枚舉關鍵字 | 命名關鍵字 | 雜項關鍵字)
6.【C 語言】編譯過程 分析 ( 預處理 | 編譯 | 匯編 | 鏈接 | 宏定義 | 條件編譯 | 編譯器指示字 )
7.【C 語言】指針 與 數組 ( 指針 | 數組 | 指針運算 | 數組訪問方式 | 字符串 | 指針數組 | 數組指針 | 多維數組 | 多維指針 | 數組參數 | 函數指針 | 復雜指針解讀)


  • 一. 函數本質
    • 1. 函數意義
      • (1) 函數來源
      • (2) 模塊化程序設計
    • 2. 面向過程的程序設計
      • (1) 程序結構
    • 3. 函數的聲明和定義
      • (1) 聲明 和 定義 的區別
      • (2) 代碼示例 ( 函數 聲明 和 定義區別 )
  • 二. 參數 可變參數 順序點 類型缺省認定
    • 1. 函數參數
      • (1) 參數分析
      • (2) 代碼示例 ( 函數參數 求值順序 )
    • 2. 程序中的順序點
      • (1) 順序點簡介
    • 3. C 語言 函數 的 缺省認定
      • (n) 標題3
    • 4.可變參數 的 定義 和 使用
      • (1) 簡介
      • (2) 代碼示例 ( 定義 使用 可變參數 )
  • 三. 函數 與 宏
    • 1. 函數 與 宏 對比案例
      • (1) 函數 和 宏 的案例
    • 2. 函數 和 宏 的分析
      • (1) 函數 和 宏 分析
    • 3. 函數 與 宏 的 利弊
      • (1) 宏 優勢 和 弊端
      • (2) 函數 的 優勢 和 弊端
      • (3) 宏的無可替代性
    • 4. 總結
      • (1) 宏 定義 和 函數 總結
  • 四. 函數的調用約定
    • 1. 函數的活動記錄 分析
      • (1) 函數的活動記錄
    • 2. 函數的調用約定概述
      • (1) 參數入棧 問題描述
      • (2) 參數傳遞順序的調用約定
  • 五. 函數設計技巧







一. 函數本質




1. 函數意義


(1) 函數來源


C 程序結構 由 數據 和 函數 組成;

函數是由匯編跳轉發展而來的 :

  • 1.匯編操作 : 匯編語言中由一系列的指令組成, 這些指令從上到下順序執行,
  • 2.跳轉操作 : 匯編中需要做分支循環操作的時候, 就是使用跳轉指令;
  • 3.指令代碼模塊 : 在匯編中有一組指令代碼, 總是需要執行這一組代碼, 需要時跳轉到該代碼處執行, 執行完畢后在跳轉回去, 這就是一個函數的雛形;
  • 4.發展 : 跳轉過來 和 跳轉回去 相當于函數的 入棧 和 出棧;


(2) 模塊化程序設計


模塊化程序設計 :

  • 1.思想 : 復雜問題拆解, 將一個復雜問題拆解成一個個的簡單問題, 這些簡單問題就可以作為一個個的函數來編寫;
  • 2.C語言程序 : 將一個復雜的程序拆解成一個個模塊 和 庫函數;

一個復雜的 C 語言程序有幾十上百萬行代碼, 這些代碼可以分解成若干模塊來實現, 即分解成一個個的函數來實現.





2. 面向過程的程序設計


(1) 程序結構


面向過程程序設計思想 :

  • 1.中心 : 整體的設計 以 過程 為中心;
  • 2.問題分解 : 將復雜問題分解為若干容易解決的問題;
  • 3.函數體現 : 面向過程 的思想在 C 語言 中的核心就是 函數;
  • 4.分解函數 : 復雜問題 分解后的過程可以分為一個個函數一步步實現;




3. 函數的聲明和定義


(1) 聲明 和 定義 的區別


聲明和定義的區別 :

  • 1.聲明 : 程序中 聲明 只是告訴編譯器 某個 實體 存在, 這個實體可以是 變量 或者 函數 等;
  • 2.定義 : 程序中定義 指的就是 某個實體 ( 函數 或 變量 ) 的實際意義;

在 test_1.c 中定義變量 int i = 10; 這是定義了 int 類型的變量, 需要為該變量分配內存空間;
在 test_2.c 中聲明變量 extern int i; 這是聲明了 int 類型的變量, 變量定義在了別的文件中, 不必為該變量分配內存空間;



(2) 代碼示例 ( 函數 聲明 和 定義區別 )


代碼示例 :

  • 1.代碼 test_1.c :
#include <stdio.h>//聲明 : 聲明外部變量, 該值是在其它文件中定義的 extern int global_int;//聲明 : 聲明函數 plus, 該函數定義在下面 int plus(int i, int j);int main() {//聲明 : 聲明函數 square, 如果不聲明編譯時會報錯, 該聲明只在 main 函數中有效果, 在main函數之外使用該方法就會報錯int square(int i);//使用函數 square, 如果沒有聲明, 編譯會報錯global_int = 3;printf("%d\n", square(global_int));//使用函數 plus, 如果沒有聲明編譯會報錯printf("%d\n", plus(1, 2));return 0; }//定義 : 定義函數 plus int plus(int i, int j) {return i + j; }//定義 : 定義函數 square int square(int i) {return i * i; }
  • 2.代碼test_2.c :
//定義 : 定義變量, 在這里需要為變量分配內存空間 int global_int;
  • 3.編譯運行結果 :






二. 參數 可變參數 順序點 類型缺省認定




1. 函數參數


(1) 參數分析


函數參數分析 :

  • 1.本質 : 函數參數的本質 與 局部變量 基本相同, 這兩種數據都存放在??臻g中 ( 中間隔著 返回地址 寄存器 EBP 數據 ) 詳情參考上一篇博客內存管理 ;
  • 2.參數值 : 函數調用的 初始值 是 函數調用時的實參值 ;

函數參數的求值順序 (盲點) :

  • 1.實現 : 函數參數的求值順序 依賴 編譯器的實現;
  • 2.操作數順序沒有在規范中 : C 語言規范中沒有規定函數參數必須從左到右進行計算賦值;
  • 3.運算符編程注意點 : C語言中大多數的運算符的操作數求值順序也是不固定的, 依賴于編譯器的實現;
  • 4.示例 : 如 int ret = fun1() * fun2(); fun1 和 fun2 函數哪個先執行, 哪個后執行 不一定;

編程時盡量不要編寫的代碼依賴于操作數的實現順序;



(2) 代碼示例 ( 函數參數 求值順序 )


代碼示例 :

  • 1.代碼 :
#include <stdio.h>int fun(int i, int j) {printf("%d, %d\n", i, j); }int main() {int m = 1;fun(m, m ++);printf("%d\n", i);/*打印出來的結果是 2, 1 \n 2分析 : 函數的參數的求值順序 不是 從左到右的, 是不固定的這個順序是編譯器制定的, 不同編譯器該順序不同*/return 0; }
  • 2.編譯運行結果 :

分析 :
函數參數計算說明 : fun(m, m ++); 進入函數體之前先計算 m 和 m++ 的值, m 和 m++ 是實參, 在計算完成之后才賦值給 i 和 j 形參;
順序點 : 在進入函數體前是一個順序點, 需要將計算完畢的實參 賦值給形參;
實參 m 賦值 : 賦值給 形參 i, 此處已經到達順序點, m 自增操作已經反映到內存中, 因此 從 內存中獲取的 i 的值是 2;
實參 m++ 賦值 : 賦值給 形參 j, m++ 表達式的計算結果是 1, 因此 j 的值是1;





2. 程序中的順序點


(1) 順序點簡介


順序點介紹 :

  • 1.順序點位置 : 順序點存在于程序之中;
  • 2.順序點定義 : 順序點是 代碼 執行過程中, 修改變量值 的 最晚時刻 ;
  • 3.順序點操作 : 程序運行到順序點時, 之前的代碼操作 都要反映到后續訪問中 ;

順序點列舉 :

  • 1.表達式結束 : 每個表達式結束都是順序點, 以分號 “;” 結尾, 每個分號的位置都是順序點;
  • 2.某些表達式的運算對象計算 : &&, || (邏輯運算), ? :(三目運算符), 逗號 表達式 中每個 運算對象計算后 是順序點;
  • 3.函數運行前 : 函數調用并且在執行函數體之前, 所有實際參數求值完之后是一個順序點, 如參數是表達式, 需要將表達式計算出結果;

順序點代碼示例 :

#include <stdio.h>int fun(int i, int j) {printf("%d, %d\n", i, j); }//注意 : 這個知識點可能過時, k = k++ + k++; 在 Ubuntu 中執行結果是 5int main() {//順序點 : 在 k = 2; 表達式以分號結束, 這是一個順序點int k = 2;int a = 1;/*順序點 : 分號結尾處是順序點, 該順序點第 1 個 k++, 計算時 k 先是 2, 自增操作到順序點時執行; 第 2 個 k++, 計算時 k 還是 2, 自增操作到順序點時執行;加法計算完畢后 k 變成 4, 兩次自增后變為 6*/k = k++ + k++;printf("k = %d\n", k);/*a-- && a 進行邏輯運算, 其中 && 是順序點, a-- 在 && 時執行 自減操作, 然后 a-- 結果變成了 0, a 的值也變成了 0, 進行邏輯與操作結果為 0 */printf("a--&&a = %d\n",a--&&a);return 0; }




3. C 語言 函數 的 缺省認定


(n) 標題3


函數缺省認定簡介 :

  • 1.描述 : C 語言中 默認 沒有類型的 參數 和 返回值 為 int 類型;
  • 2.舉例 :
fun(i) {return i }

等價于

int fun(int i) {return i; }
  • 3.代碼示例 :
#include <stdio.h>//函數缺省認定 : 沒有類型的 參數 和 返回值 為 int 類型 fun(i, j) {return i + j; }int main() {printf("fun(i, j) = %d\n",fun(3, 3));return 0; }





4.可變參數 的 定義 和 使用


(1) 簡介


可變參數簡介 :

  • 1.描述 : 函數可以接收的參數個數是不定的, 根據調用的需求決定有幾個參數;
  • 2.依賴頭文件 : 如果要使用可變參數, 需要導入 stdarg.h 頭文件;
  • 3.核心用法 : va_list, va_start, va_end, va_arg 配合使用, 訪問可變參數值;

可變參數示例 :

  • 1.函數名相同, 參數個數不同 : open 函數, 有兩種用法, 一個有 2 個參數 int open(const char *pathname, int flags) , 一個有三個參數 int open(const char *pathname, int flags, mode_t mode) , C 語言中明顯沒有重載, 這里是用可變參數來實現的 ; 使用 man 2 open 命令查看 open 函數的文檔;

可變參數的注意點 :

  • 1.取值必須順序進行 : 讀取可變參數的值時, 必須從頭到尾按照前后順序讀取, 不能跳過任何一個參數;
  • 2.必須確定1個參數 : 參數列表中必須有一個命名確定的參數;
  • 3.可變參數數量無法確定 : 使用 va_arg 獲取 va_list 中的值時, 無法判斷實際有多少個參數;
  • 4.可變參數類型無法確定 : 使用 va_arg 獲取 va_list 中的值時, 無法判斷某個參數是什么類型的;

依次讀取可變參數時, 注意 可變參數 的 數量 和 類型, 每個位置的參數 是 什么類型, 一定不要讀取錯誤, 否則會產生不可預測的后果;



(2) 代碼示例 ( 定義 使用 可變參數 )


代碼示例 :

  • 1.代碼 :
#include <stdio.h> #include <stdarg.h>/*定義可變參數 : ① 列出第一個參數 int a② 使用 ... 表明后面有 個數不定 并且 類型不定 的 參數 */ double avg(int arg_count, ...) {va_list args;int i = 0; //循環控制變量double sum = 0; //統計參數之和//初始化列表, 讓列表準備取值va_start(args, arg_count);for(i = 0; i < arg_count; i ++){//從可變參數列表中獲取數據, 數據類型是 int 類型sum = sum + va_arg(args, int);}//結束使用可變參數列表va_end(args);return sum / arg_count; }int main() {//使用定義了可變參數的函數, 傳入 11 個參數printf("%f\n", avg(10, 1, 2, 3, 4, 5 , 6, 7, 8, 9, 10));//使用定義了可變參數的函數, 傳入 4 個參數printf("%f\n", avg(3, 444, 555, 666));return 0; }
  • 2.編譯運行結果 :






三. 函數 與 宏




1. 函數 與 宏 對比案例


(1) 函數 和 宏 的案例


代碼示例 : 分別使用 函數 和 宏 將數組數據清零;

  • 1.代碼 :
#include <stdio.h>/*定義宏 : 這個宏的作用是將 p 目前是 void* 類型, 轉為 char* 類型, 將后將每個字節的內容都設置為 0 */ #define RESET(p, len) while(len > 0) ((char*)p)[--len] = 0;/*定義函數 : 也是將 p 指向的 len 字節的內存置空 */ void reset(void* p, int len) {while(len > 0){((char*)p)[--len] = 0;} }int main() {//1. 定義兩個數組, 用函數 和 宏 不同的方式重置數據int array1[] = {1, 2, 3};int array2[] = {4, 5, 6, 7};//2. 獲取兩個數組大小int len1 = sizeof(array1);int len2 = sizeof(array2);//3. 定義循環控制變量int i = 0;//4. 打印兩個數組處理前的數據printf("打印array1 : \n");for( i = 0; i < 3; i ++){printf("array1[%d] = %d \n", i, array1[i]);}printf("打印array2 : \n");for( i = 0; i < 4; i ++){printf("array2[%d] = %d \n", i, array2[i]);}//5. 使用宏的方式處理數組1RESET(array1, len1);//6. 使用函數的方式處理數組2reset(array2, len2);//7. 打印處理后的數組printf("打印處理后的array1 : \n");for( i = 0; i < 3; i ++){printf("array1[%d] = %d \n", i, array1[i]);}printf("打印處理后的array2 : \n");for( i = 0; i < 4; i ++){printf("array2[%d] = %d \n", i, array2[i]);}return 0; }
  • 2.編譯運行結果 :

雖然看起來 函數 和 宏實現了相同的功能, 但是它們有很大的區別;





2. 函數 和 宏 的分析


(1) 函數 和 宏 分析


函數 和 宏 分析 :

  • 1.宏處理 : 宏定義是在預處理階段直接進行宏替換, 代碼直接復制到宏調用的位置, 由于宏在預處理階段就被處理了, 編譯器是不知道宏的存在的;
  • 2.函數處理 : 函數是需要編譯器進行編譯的, 編譯器有決定函數調用行為的義務;
  • 3.宏的弊端 ( 代碼量 ) : 每調用一次宏, 在預處理階段都要進行一次宏替換, 會造成代碼量的增加;
  • 4.函數優勢 ( 代碼量 ) : 函數執行是通過跳轉來實現的, 代碼量不會增加;
  • 5.宏的優勢 ( 效率 ) : 宏 的執行效率 高于 函數, 宏定義是在預編譯階段直接進行代碼替換, 沒有調用開銷;
  • 6.函數的弊端 ( 效率 ) : 函數執行的時候需要跳轉, 以及創建對應的活動記錄( 棧 ), 效率要低于宏;




3. 函數 與 宏 的 利弊


(1) 宏 優勢 和 弊端


宏的優勢和弊端 : 宏的執行效率要高于函數, 但是使用宏會有很大的副作用, 非常容易出錯, 下面的例子說明這種弊端;

代碼示例 :

  • 1.代碼 :
#include <stdio.h>#define ADD(a, b) a + b #define MUL(a, b) a * b #define _MIN_(a, b) ((a) < (b) ? (a) : b)int main() {int a = 1, b = 10;//宏替換的結果是 : 2 + 3 * 4 + 5, 最終打印結果是 19printf("%d\n", MUL(ADD(2, 3), ADD(4, 5)));//宏替換的結果是 ((a++) < (b) ? (a++) : b), 打印結果是 2printf("%d\n", _MIN_(a++, b));return 0; }
  • 2.編譯運行結果 :
  • 3.查看預編譯文件 : 使用 gcc -E test_1.c -o test_1.i 指令, 將預編譯文件輸出到 test_1.i 目錄中; 下面是預編譯文件的一部分 ;
int main() {int a = 1, b = 10;printf("%d\n", 2 + 3 * 4 + 5);printf("%d\n", ((a++) < (b) ? (a++) : b));return 0; }


(2) 函數 的 優勢 和 弊端


函數的優缺點 :

  • 1.函數優勢 : 函數調用需要將實參傳遞給形參, 沒有宏替換這樣的副作用;
  • 2.弊端 ( 效率低 ) : 函數執行需要跳轉, 同時也需要建立活動對象對象 ( 如 函數棧 ) 來存儲相關的信息, 需要犧牲一些性能;


(3) 宏的無可替代性


宏 定義 優勢 :

  • 1.宏參數不限定類型 : 宏參數 可以是 任何 C 語言 的實體類型, 如 int, float, char, double 等;
  • 2.宏參數可以使類型名稱 : 類型的名稱也可以作為宏的參數;
//宏定義 : 實現分配 n 個 type 類型空間, 并返回 type 類型指針 #define MALLOC(type, n) (type*)malloc(n * sizeof(type))//分配 5 個 float 大小的動態空間, 并將首地址存放在 指針 p 中; float *p = MALLOC(int, 5);




4. 總結


(1) 宏 定義 和 函數 總結


宏定義 和 函數 小結 :

  • 1.宏定義 : 宏 的 參數 可以 是 C 語言中 的 任何類型的 ( 優勢 ) , 宏的執行效率 高 ( 優勢 ), 但是容易出錯 ( 弊端 );
  • 2.函數 : 函數 參數 的 類型是固定的, 其 執行效率低于宏, 但是不容易出錯;
  • 3.宏定義 和 函數之間的關系 : 這兩者不是競爭對手, 宏定義可以實現一些函數無法實現的功能;






四. 函數的調用約定




1. 函數的活動記錄 分析


(1) 函數的活動記錄


活動記錄概述 : 函數調用時 將 下面一系列的信息 記錄在 活動記錄中 ;

  • 1.臨時變量域 : 存放一些運算的臨時變量的值, 如自增運算, 在到順序點之前的數值是存在臨時變量域中的;

    后置操作 自增 原理 : i++ 自增運算 進行的操作 :
    ( 1 ) 生成臨時變量 : 在內存中生成臨時變量 tmp ;
    ( 2 ) 臨時變量賦值 : 將 i 的值賦值給臨時變量, tmp = i ;
    ( 3 ) 進行加 1 操作 : 將 i + 1 并賦值給 i;

    示例 : 定義函數 fun(int a, int b), 傳入 fun(i, i++), 傳入后 獲取的實參值分別是 2 和 1;
    在函數傳入參數達到順序點之后開始取值, 函數到達順序點之后, 上面的三個步驟就執行完畢, 形參 a 從內存中取值, i 的值是2, 形參 b 從臨時變量域中取值, 即 tmp 的值, 取值是 1;

  • 2.局部變量域 : 用于存放 函數 中定義 的局部變量, 該變量的生命周期是局部變量執行完畢;

  • 3.機器狀態域 : 保存 函數調用 之前 機器狀態 相關信息, 包括 寄存器值 和 返回地址, 如 esp 指針, ebp 指針;
  • 4.實參數域 : 保存 函數的實參信息 ;
  • 5.返回值域 : 存放 函數的返回值 ;




2. 函數的調用約定概述


(1) 參數入棧 問題描述


參數入棧問題 : 函數參數的計算次序是不固定的, 嚴重依賴于編譯器的實現, 編譯器中函數參數入棧次序;

  • 1.參數傳遞順序 : 函數的參數 實參傳遞給形參 是從左到右傳遞 還是 從右到左傳遞;
  • 2.堆棧清理 : 是函數的調用者清理 還是 由 函數本身清理 ;


參數入棧 棧維護 問題示例 :

  • 1.多參數函數定義 : 定義一個函數 fun(int a, int b, int c) , 其中有 3 個參數;
  • 2.函數調用 : 當發生函數調用時 fun(1, 2, 3), 傳入三個 int 類型的參數, 這三個參數肯定有一個傳遞順序, 這個傳遞順序可以約定;
    • ( 1 ) 從左向右入棧 : 將 1, 2, 3 依次 傳入 函數中 ;
    • ( 2 ) 從右向左入棧 : 將 3, 2, 1 依次 傳入 函數中 ;
  • 3.棧維護 : 在 fun1() 函數中 調用 fun2() 函數, 會創建 fun2() 函數的 活動記錄 (棧), 當 fun2() 函數執行完畢 返回的時候, 該 fun2 函數的棧空間是由誰 ( fun1 或 fun2 函數 ) 負責釋放的;

函數參數計算次序依賴于編輯器實現, 函數參數入棧的順序可以自己設置;



(2) 參數傳遞順序的調用約定


函數參數調用約定 :

  • 1.函數調用行為 : 函數調用時 參數 傳遞給 被調用的 函數, 返回值被返回給 調用函數 ;
  • 2.調用約定作用 : 調用約定 是 用來規定 ① 參數 是通過什么方式 傳遞到 ??臻g ( 活動記錄 ) 中, ② 棧 由誰來 清理 ;
  • 3.參數傳遞順序 ( 右到左 ) : 從右到左入棧使用 __stdcall, __cdecl, __thiscall 關鍵字, 放在 函數返回值之前;
  • 4.參數傳遞順序 ( 左到右 ) : 從左到右入棧使用 __pascal, __fastcall 關鍵字, 放在 函數返回值之前;
  • 5.調用堆棧的清理工作 : ① 調用者負責清理調用堆棧; ② 被調用的函數返回之前清理堆棧;






五. 函數設計技巧





函數設計技巧 :

  • 1.避免使用全局變量 : 在函數中盡量避免使用全局變量, 讓函數形成一個獨立功能模塊;
  • 2.參數傳遞全局變量 : 如果必須使用到全局變量, 那么多設計一個參數, 用于傳入全局變量;
  • 3.參數名稱可讀性 : 盡量不要使用無意義的字符串作為參數變量名;
  • 4.參數常量 : 如果參數是一個指針, 該指針僅用于輸入作用, 盡量使用 const 修飾該指針參數, 防止該指針在函數體內被修改;
//這里第二個參數僅用于輸入, 不需要修改該指針, 那么就將該參數設置成常量參數 void fun(char *dst, const char* src);
  • 5.返回類型不能省略 : 函數的返回類型不能省略, 如果省略了返回值, 那么返回值默認 int;
  • 6.參數檢測 : 在函數開始位置, 需要檢測函數參數的合法性, 避免不必要的錯誤, 尤其是指針類型的參數;
  • 7.棧內存指針 : 返回值 絕對不能是 局部變量指針, 即 指針指向的位置是 棧內存位置, 棧內存在返回時會銷毀, 不能再函數運行結束后使用 ;
  • 8.代碼量 : 函數的代碼量盡量控制在一定數目, 50 ~ 80 行, 符合模塊化設計規則;
  • 9.輸入輸出固定 : 函數在輸入相同的參數, 其輸出也要相同, 盡量不要在函數體內使用 static 局部變量, 這樣函數帶記憶功能, 增加函數的復雜度;
  • 10.參數控制 : 編寫函數的時候, 函數的參數盡量控制在 4 個以內, 方便使用;
  • 11.函數返回值設計 : 有時候函數不需要返回值, 或者返回值使用指針參數設置, 但是為了增加靈活性, 可以附加返回值; 如 支持 鏈式表達式 功能;

總結

以上是生活随笔為你收集整理的【C 语言】C 语言 函数 详解 ( 函数本质 | 顺序点 | 可变参数 | 函数调用 | 函数活动记录 | 函数设计 ) [ C语言核心概念 ]的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。