研究了下变参函数,测试代码如下:
-
#include <stdarg.h>
-
#include <stdio.h>
-
-
void vl_printf(const char *format, ...)
-
{
-
unsigned char buf[256];
-
va_list args;
-
va_start(args, format);
-
vsprintf(buf, format, args);
-
puts(buf);
-
va_end(args);
-
}
-
-
int add(int num, ...)
-
{
-
int sum = 0;
-
va_list datas;
-
va_start(datas, num);
-
sum+=va_arg(datas, int);
-
sum+=va_arg(datas, int);
-
va_end(datas);
-
sum+=va_arg(datas, int);
-
return sum;
-
}
-
-
void main()
-
{
-
int sum = 0;
-
vl_printf("%s, %d", "123", 123);
-
sum = add(3, 1);
-
}
自己写了段代码测试了下效果,然后看了下对应的汇编,得出自己的一些理解。
使用变参一般步骤:
1. va_list args;
可理解为定义一个指向可变参数列表的指针变量void * args;
2. va_start(args, format);
获取第一个可变参数的地址。因为可变参数在函数调用时保存在栈中,可根据函数中第一个参数在栈中的地址获取它之后的第一个可变参数的地址, 赋值给指针变量args
3. var_args(args, int); 获取参数的值
根据可变参数的地址,再由参数的类型,可获取该参数的值, 然后指针指向下一个参数。相当于
int val = (*(int *)args)); args +=4;
第20行代码有问题,因为此时args指向的已经是栈中可变参数之后的内容
4. var_end(args);
把参数列表指针设置为空args=NULL,所以第22行代码会执行出错
用VC观察datas的值和datas指向的内存区域的值,更容易理解。
阅读(1178) | 评论(0) | 转发(0) |