程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 設計變長參數的函數《精通Unix下C語言編程與項目實踐》之二

設計變長參數的函數《精通Unix下C語言編程與項目實踐》之二

編輯:關於C語言

精通Unix下C語言編程與項目實踐之二 函數的變長參數 作者:朱雲翔,胡平 5.4 函數的變長參數   文件的格式化輸入輸出函數都支持變長參數。定義時,變長參數列表通過省略號“…”表示,因此,具有變長參數列表的函數定義格式為: type 函數名(參數1, 參數2, 參數n, ...); 其中type為函數的返回值類型,參數1~參數n為定長參數,“...”代表變長參數,注意“...”必須定義在參數的最右端。如下例: int printf(const char *format, ...); int mysum(...);

5.4.1. 變長參數的使用

Unix的變長參數通過va_list對象實現,定義在文件“stdarg.h”中,變長參數的應用模板如代碼5-15所示: 代碼5-15 變長參數代碼模板 #include <stdarg.h> function (parmN, ...) va_list pvar; …………………………… va_start (pvar, parmN); while() {     ……………………     f = va_arg (pvar, type);     …………………… } va_end (pvar);

1. va_list pvar

申明va_list數據類型變量pvar,該變量訪問變長參數列表中的參數。

2. va_start(pvar, parmN)

宏va_start初始化變長參數列表。pvar是va_list型變量,在步驟1中定義,記載列表中的參數信息。parmN是省略號“...”前的一個參數名,va_start根據此參數,判斷參數列表的起始位置,如: 例1. 函數:function(parmN, …) 答:va_start(pvar, parmN); 例2. 函數:int mysum(int i, int j, …) 答:va_start(pvar, j);

3. va_arg(pvar, type)

獲取變長參數列表中參數的值。pvar是步驟1中定義的va_list型變量,type為參數值的類型,也是宏va_arg返回數值的類型,如: va_arg(pvar, int);          /* 將參數列表中的當前參數值轉化為int型返回 */ va_arg(pvar, float);        /* 將參數列表中的當前參數值轉化為float型返回*/ 宏va_arg執行完畢後自動更改對象pvar,將其指向下一個參數。

4. va_end(pvar)

關閉本次對變長參數列表的訪問。

實例

設計函數mysum,計算輸入參數的和並返回結果。源程序如代碼5-16所示: 代碼5-16 變長參數函數實例節自/code/chapter5/mysum.c) #include <stdarg.h> int mysum(int i, ...)   /* 參數i表明變長參數的個數 */ {     int r=0, j=0;     va_list pvar;     va_start(pvar, i);     for (j=0; j<i; j++)     {         r += va_arg(pvar, int);     }     va_end(pvar);     return(r); } void main() {     printf("sum(1,4)=%d\n", mysum(1, 4));     printf("sum(2,4,8)=%d\n", mysum(2, 4, 8)); } 編譯與運行代碼5-16: # make mysum        cc -O -o mysum mysum.c # ./mysum sum(1,4)=4 sum=(2,4,8)=12

5.4.2 變長參數的傳遞

上一節講述了如何創建具有變長參數的函數和如何讀取變長參數,其操作都在函數內完成,本節將講述把變長參數列表整體作為參數傳遞給其他函數的方法。 變長參數傳遞的函數族如下: #include <stdarg.h> int vprintf(const char *format, va_list ap); int vfprintf(FILE *stream, const char *format, va_list ap); int vsprintf(char *str, const char *format, va_list ap); 這些函數完全等價於格式化輸出函數,只是在形式上采用固定參數代替變長參數,這樣描述的函數更加緊湊,這些函數常應用於變長參數函數內部的功能實現。

實例

設計函數“int PrintLog(FILE* stream, const char* pformat, ...)”,它按照字符串format的內容,控制後繼參數的數量和格式,並在文件流stream中輸出。源程序如代碼5-17所示: 代碼5-17 傳遞變長參數實例節自/code/chapter5/print1.c) #include <stdarg.h> #include <stdio.h> int PrintLog(FILE* pfile, const char * pformat, ...) {     va_list _va_list;     char szBuf[1024];        if (pformat == NULL || pfile == NULL) return -1;        /* 判斷指針是否正確*/     va_start(_va_list, pformat);                    /* 初始化變長參數列表 */     vsprintf(szBuf, pformat, _va_list);             /* 傳遞變長參數 */     va_end(_va_list);                               /* 結束使用變長參數列表 */     fputs(szBuf, pfile);                            /* 輸出到文件流 */     return 0; } void main() {     PrintLog(stderr, "[%s][%s][%d][%c]\n", "This", "Is", 5, 'a');     PrintLog(stderr, "Error[%p][%.2f][%X]\n", NULL, 3.123, 100); } 編譯與運行代碼5-17: # make print1         cc -O print1.c  -o print1 # ./print1     [This][Is][5][a] Error[00000000][3.12][64] 實踐經驗】對於指針類型的參數,最好在函數入口處判斷其是否為空,以免空指針引用錯誤。如代碼5-17中黑體部分。   相關文章: 封面          前言        目錄         策劃         作者 動態庫        變長參數    文件鎖

本文出自 “編程浪子朱雲翔” 博客,請務必保留此出處http://zhuyunxiang.blog.51cto.com/653596/129767

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved