这几天遇到的问题,我想写一个可变参数的函数。
于是了解到c可以做到,查看man里的定义,可知:
-
va_list:用来保存宏va_start、va_arg和va_end所需信息的一种类型。为了访问变长参数列表中的参数,必须声明va_list类型的一个对象
-
va_start:访问变长参数列表中的参数之前使用的宏,它初始化用va_list声明的对象,初始化结果供宏va_arg和 va_end使用;
-
va_arg: 展开成一个表达式的宏,该表达式具有变长参数列表中下一个参数的值和类型。每次调用va_arg都会修改用va_list声明的对象,从而使该对象指向参数列表中的下一个参数;
-
va_end:该宏使程序能够从变长参数列表用宏va_start引用的函数中正常返回。
这些宏定义在stdarg.h中,所以用到可变参数的程序应该包含这个头文件.
代码例程:
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
typedef struct TAG_MY_STRUCT
{
int a;
float b;
char c;
double d;
}myStruct, *pMyStruct;
void var_test(char *fmt, ...)
{
va_list va_ptr;
char *tmpP = NULL;//测试字符串指针
int *tmpP2 = NULL;//测试整形指针
double tmpF = 0.00f;//测试双精度浮点指针
va_start(va_ptr,fmt);//起始,第一个参数指针
//打印前面三个参数,分别是字符串,整型,整型(不支持直接输入char,只支持整型)
printf("LDbg. arg1: %s. arg2: %d, arg3:%c.\n", fmt, va_arg(va_ptr,int), va_arg(va_ptr, int));
//第四个参数,字符串指针,获取到临时指针,通过临时指针打印字符串,不能直接打印va_arg里面获取到的。
tmpP = va_arg(va_ptr, char*);
printf("tmp char: %s.\n", tmpP);
//第五个参数,双精度浮点数,不支持单精度flaot,默认传入如是浮点,都认为是double
tmpF = va_arg(va_ptr, double);
printf("double : %f\n",tmpF);
//第六个参数,整型指针,是一个结构体,把这个结构体的全部成员打印出来,对比是否正确,测试正确
tmpP2 = va_arg(va_ptr, int*);
printf("struct pointer: %p, mem.a(should be 11)=%d, mem.b(shoule be 0.5)=%f, mem.c(shoule be a)=%c, mem.d(should be 0.0123f):%f.\n",
tmpP2, ((pMyStruct)tmpP2)->a, ((pMyStruct)tmpP2)->b,((pMyStruct)tmpP2)->c,((pMyStruct)tmpP2)->d);
//第七个参数,普通整型指针的传入,这个经常用到,需要测试。
tmpP2 = va_arg(va_ptr, int*);
printf("int prt: %p\n", tmpP2);
va_end(va_ptr);
}
void main(void)
{
pMyStruct p1;
myStruct struct1;
struct1.a = 11;
struct1.b = 0.5f;
struct1.c = 'a';
struct1.d = 0.00123f;
p1 = &struct1;
int *intPtr = 0x123456;
var_test("hello kyland", 55, 'c', "second string", 0.123f, p1, intPtr);
}