va_start、va_end、va_list的使用
http://www.cnblogs.com/rainduck/archive/2010/11/10/1873417.html
?1:當無法列出傳遞函數的所有實參的類型和數目時,可用省略號指定參數表
void foo(...);
void
foo(parm_list,...);
2:函數參數的傳遞原理
函數參數是以數據結構:棧的形式存取,從右至左入棧.
?
3:獲取省略號指定的參數
在函數體中聲明一個va_list,然后用va_start函數來獲取參數列表中的參數,使用完畢后調用va_end()結束。像這段代碼:
?
4.va_start使argp指向第一個可選參數。va_arg返回參數列表中的當前參數并使argp指向參數列表中的下一個參數。va_end把argp指針清為NULL。函數體內可以多次遍歷這些參數,但是都必須以va_start開始,并以va_end結尾。
1).
#include <stdio.h> #include <string.h> #include <stdarg.h>int demo(char*, ...);int main(void) {demo("DEMO", "This", "is", "a", "demo!", ""); }int demo(char* msg, ...) {va_list argp;int argno = 0;char* para;va_start(argp, msg);while (1){para = va_arg(argp,char*);if (strcmp(para, "") == 0)break;printf("Parameter #%d is: %s\n", argno, para);argno++;}va_end(argp);return 0; }?
2).
#include <stdio.h> #include <stdarg.h>void simple_va_fun(int start, ...) {va_list arg_ptr;int nArgValue = start;int nArgCount = 0;va_start(arg_ptr, start);do {++nArgCount;printf("the %d th arg: %d\n", nArgCount, nArgValue);//輸出各參數的值nArgValue = va_arg(arg_ptr,int);//得到下一個可變參數的值} while (nArgValue != -1);return; }int main(int argc, char * argv[]) {simple_va_fun(100, -1);simple_va_fun(100, 200, -1);return 0; }3).
#include <stdio.h> #include <stdlib.h>//一個簡單的類似于printf的實現,//參數必須都是int 類型 void myprintf(char* fmt, ...) {char* pArg = NULL; //等價于原來的va_listchar c;pArg = (char*) &fmt; //注意不要寫成p = fmt!!因為這里要對參數取址,而不是取值pArg += sizeof(fmt); //等價于原來的va_startdo {c = *fmt;if (c != '%'){putchar(c); //照原樣輸出字符 }else{ //按格式字符輸出數據switch (*++fmt){case 'd':printf("%d", *((int*) pArg));break;case 'x':printf("%#x", *((int*) pArg));break;default:break;}pArg += sizeof(int);//等價于原來的va_arg }++fmt;} while (*fmt != '\0');pArg = NULL; //等價于va_endreturn; }int main(int argc, char* argv[]) {int i = 1234;int j = 5678;myprintf("the first test:i=%d\n", i, j);myprintf("the secend test:i=%d;%x;j=%d;\n", i, 0xabcd, j);system("pause");return 0; }?還記得printf函數調用的時候那個“...”嗎?就是可以輸入任意的參數。現在你用va_list也可以實現類似的函數聲明,printf就是這樣做的。
?va_list args; ?? ??? ??? ??? ? //聲明變量
?va_start(args,? before); ?? ? //開始解析。args指向before后面的參數
?參數類型 var = va_arg(args,? 參數類型);//取下一個參數并返回。args指向下一個參數
?va_end(args); //結束解析
總結
以上是生活随笔為你收集整理的va_start、va_end、va_list的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java代码实现通讯录实例,我不知道这有
- 下一篇: 降息还是加息?