VA_LIST
C语言中解决变参问题的一组宏,变参问题是指参数的个数不定,可以是传入一个参数也可以是多个;可变参数中的每个参数的类型可以不同,也可以相同。
va_list 用法:
- 在函数里定义一具VA_LIST型的变量,这个变量是指向参数的指针;
- 然后用VA_START宏初始化变量刚定义的VA_LIST变量;
- 然后用VA_ARG返回可变的参数,VA_ARG的第二个参数是你要返回的参数的类型(如果函数有多个可变参数的,依次调用VA_ARG获取各个参数);
- 最后用VA_END宏结束可变参数的获取。
va_list 用法示例:
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
void write_log( char *fmt, ...){
va_list va;
char buf[1024];
va_start(va, fmt);
memset(buf, 0, 1024);
(void) vsprintf(buf, fmt, va);
va_end(va);
printf("%s-%s", "my_log_prehead", buf);
}
void read_num(int num, ...)
{
va_list va; /*point to each unamed variables in arg list*/
va_start(va, num); /*start va_list from num, and va goes to the second one, and this is the first vary variable*/
while(num--) {
printf("%d\t", va_arg(va, int)); /*get a arg, va goes to the next*/
}
va_end(va); /*end the va*/
}
int main(){
write_log("%s\n", "hello world!");
read_num(3, 111, 222, 333);
return 0;
}
结果输出:
my_log_prehead-hello world!
111 222 333
va_list 原理:
- 简化版定义:
#define va_list char *
#define va_start(p, first) (p = (va_list)&first + sizeof(first))
#define va_arg(p, next) (*(next*)((p += sizeof(next) ) - sizeof(next)))
#define va_end(p) (p = (va_list)NULL)
- 由于参数的地址用于VA_START宏,所以参数不能声明为寄存器变量,或作为函数或数组类型。