int ejArgs(int argc, char_t **argv, char_t *fmt, ...) { va_list vargs; char_t *cp, **sp; int *ip; int argn; /* va_start(va_list vap, 最后一个普通参数) va_start(vargs, fmt); 相当于 char *vargs= (char *)&fmt + sizeof(int); 此时vap正好指向n后面的可变参数表中的第一个参数。 实质是宏定义: #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) */ va_start(vargs, fmt); if (argv == NULL) { return 0; } for (argn = 0, cp = fmt; cp && *cp && argv[argn]; ) { if (*cp++ != '%') { continue; } switch (*cp) { case 'd': /* 类型 va_arg(va_list vargs, 类型名) 取得可变变量参数地址 在第一次使用va-arg时,它返回可变参数表中的第一个参数,后续的调用都返回表中的下一个参数 实质是宏定义: #define va_arg(ap,type) ( *(type *)((ap += _INTSIZEOF(type)) - _INTSIZEOF(type)) ) */ ip = va_arg(vargs, int*); *ip = gatoi(argv[argn]); break; case 's': sp = va_arg(vargs, char_t**); *sp = argv[argn]; break; default: a_assert(0); } argn++; } /* 功能就是把指针ap赋值为0,使它不指向内存的变量 实质是宏定义: #define va_end(ap) ( ap = (va_list)0 ) */ va_end(vargs); return argn; }
使用:
ejArgs(argc, argv, T("%d %s"), &type, &field);
中心点:
函数调用中,参数在堆栈中是顺序存放,取得最后一个普通参数地址,可以依次取得堆栈中存放的其他参数地址。
参考博客:
http://blog.csdn.net/hackbuteer1/article/details/7558979#