今天在看**的時候,看到了這樣一段除錯的**,搞不清楚(...)這個是什麼意思,看了下相關資料,簡單記錄下。
#ifdef debug
#define dbg(...) fprintf(stderr, " dbg(%s, %s(), %d): ", __file__, __function__, __line__); fprintf(stderr, __va_args__)
#else
#define dbg(...)
#endif
1、printf**
printf
(「hello,world!」);其引數個數為1個。
printf
(「a=%d,b=%s,c=%c」,a,b,c);其引數個數為4個。
如何編寫可變引數函式呢?我們首先來看看printf函式原型是如何定義的。
在linux下,輸入man 3 printf,可以看到prinf函式原型如下:
synopsis
#include
int
printf
(
const
char
*format, ...);
後面的三個點...表示printf引數個數是不定的.
如何實現可變引數函式?
2. 編寫可變函式準備
為了編寫可變引數函式,我們通常需要用到頭檔案下定義的以下函式:
void
va_start
(
va_list
ap, last);
type
va_arg
(
va_list
ap, type);
void
va_end
(
va_list
ap);
void
va_copy(
va_list
dest,
va_list
src);
其中:va_list是用於存放引數列表的資料結構。
va_start函式根據初始化last來初始化引數列表。
va_arg函式用於從引數列表中取出乙個引數,引數型別由type指定。
va_copy函式用於複製引數列表。
va_end函式執行清理引數列表的工作。
上述函式通常用巨集來實現,例如標準ansi形式下,這些巨集的定義是:
typedef
char
*
va_list
;
//字串指標
#define _intsizeof(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _intsizeof(v) )
#define va_arg(ap,t) ( *(t *)((ap += _intsizeof(t)) - _intsizeof(t)) )
#define va_end(ap) = (va_list)0 )
使用巨集_intsizeof是為了按照整數位元組對齊指標,因為c呼叫協議下面,引數入棧都是整數位元組(指標或者值)。
4、用va_list實現vprintf()示例
#include #include void my_printf(const char *format, ...)
int main(int argc, char *argv)
5、c語言可變引數函式簡單例項
引數列表的格式是強制性引數在前,後面跟著乙個逗號和省略號(...),這個省略號代表可選引數。
可變引數函式要獲取可選引數時,必須通過乙個型別為 va_list 的物件,它包含了引數資訊。這種型別的物件也稱為引數指標(argument pointer),它包含了棧中至少乙個引數的位置。可以使用這個引數指標從乙個可選引數移動到下乙個可選引數,由此,函式就可以獲取所有的可選引數。va_list 型別被定義在標頭檔案 stdarg.h 中。
乙個簡單的例子,說明可變引數的用法
#include #include int ******(int num,...) //num代表了要傳遞的可變引數的總數
va_end(vl);//結束標誌
return result;
}int main(int argc, char **argv)
執行結果如下:
c 語言可變引數
1 當無法列出傳遞函式的所有實參的型別和數目時,可用省略號指定參數列 void foo void foo parm list,2 函式引數的傳遞原理 函式引數是以資料結構 棧的形式訪問,從右至左入棧.eg include void fun int a,int main output 12 343 獲...
c語言可變引數
ifdef debug print info x printk x,else print info x endif 一 什麼是可變引數 我們在c語言程式設計中有時會遇到一些引數個數可變的函式,例如printf 函式,其函式原型為 int printf const char format,它除了有乙個...
C語言可變引數
在gnu c中,巨集可以接受可變數目的引數,就象函式一樣,例如 1 2 define pr debug fmt,arg.printk kern debug fmt,arg 用可變引數巨集 variadic macros 傳遞可變參數列 你可能很熟悉在函式中使用可變參數列,如 1 voidprintf...