【C】 45_函數參數的祕密 (下)

  • 函數參數的計算次序是依賴編譯器實現的,那麼函數參數的入棧次序是如何肯定的呢?

strcpy(s, "D.T.Software");函數

調用約定

  • 當函數調用發生時this

    • 參數會傳遞給被調用的函數
    • 而返回值會被返回給函數調用者
  • 調用約定描述參數如何傳遞到棧中以及棧的維護方式spa

    • 參數傳遞順序
    • 調用棧清理
  • 調用約定是預約義的可理解爲調用協議
  • 調用約定一般用於庫調用和庫開發的時候設計

    • 從右向左依次入棧: __stdcall, __cdecl, __thiscall
    • 從左向右依次入棧:__pascal, __fastcall

c 語言編譯器的默認調用預約, 從右向左依次入棧code

clipboard.png

當程序中須要使用第三方庫文件時,須要考慮調用約定是否一致ip

例:
主程序C語言編寫,C語言編譯器編譯,默認從右向左的入棧順序;
庫文件pascal語言編寫,pascal語言編譯器編譯,默認從左向右的入棧順序;
當 C 主程序調用 pascal 語言完成的庫文件時,C 主程序中須要顯示的聲明調用約定。開發

可變參數

  • C語言中能夠定義參數可變的函數
  • 參數可變函數的實現依賴於 stdarg.h 頭文件編譯器

    • va_list - 參數集合
    • va_arg - 取具體參數值
    • va_start - 標識參數訪問的開始
    • va_end - 標識參數訪問的結束

實例分析: 編寫函數計算平均值

#include <stdio.h>
#include <stdarg.h>

float average(int n, ...)
{
    va_list args;
    int i = 0;
    float sum = 0;
    
    va_start(args, n);
    
    for(i=0; i<n; i++)
    {
        sum += va_arg(args, int);
    }
    
    va_end(args);
    
    return sum / n;
}

int main()
{
    printf("%f\n", average(5, 1, 2, 3, 4, 5));
    printf("%f\n", average(4, 1, 2, 3, 4));

    return 0;
}
輸出:
3.000000
2.500000

可變參數的限制

  • 可變參數必須從頭至尾按照順序逐個訪問
  • 參數列表中至少存在一個肯定的命名參數
  • 可變參數函數沒法肯定實際存在的參數的數量
  • 可變參數函數沒法肯定參數的實際類型

注意:va_arg 中若是指定了錯誤的類型,那麼結果是不可預測的。it

小結

  • 調用約定指定了函數參數的入棧順序以及棧的清理方式
  • 可變參數是 C 語言提供的一種函數設計技巧
  • 可變參數的函數提供了一種更方便的函數調用方式
  • 可變參數必須順序的訪問,沒法直接訪問中間的參數值

以上內容參考狄泰軟件學院系列課程,請你們保護原創!io

相關文章
相關標籤/搜索