va_list简介
可变参数列表,主要处理传参时参数属性不确定的情况。实现及作用如下:
INTSIZEOF 宏,获取类型占用的空间长度,最小占用长度为int的整数倍:
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
VA_START宏,获取可变参数列表的第一个参数的地址(ap是类型为va_list的指针,v是可变参数最左边的参数):
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
VA_ARG宏,获取可变参数的当前参数,返回指定类型并将指针指向下一参数(t参数描述了当前参数的类型):
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
VA_END宏,清空va_list可变参数列表:
#define va_end(ap) ( ap = (va_list)0 )
va_list使用步骤
(1)首先在函数里定义一具VA_LIST型的变量,这个变量是指向参数的指针;
(2)然后用VA_START宏初始化刚定义的VA_LIST变量;
(3)然后用VA_ARG返回可变的参数,VA_ARG的第二个参数是你要返回的参数的类型(如果函数有多个可变参数的,依次调用VA_ARG获取各个参数);
(4)最后用VA_END宏结束可变参数的获取。
举例
#include <stdio.h>
#include <stdarg.h>
int findMax(int n,...)
{
va_list arg;
int i = 0,M = 0;
va_start(arg, n);
for(i=0; i<n; i++)
{
int m = va_arg(arg,int);
if(m > M)
{
M = m;
}
}
va_end(arg);//相当于p = NULL
return M;
}
int main()
{
int max = findMax(5, 1, 2, 3, 4, 5);
printf("max = %d\n", max);
return 0;
}
//输出结果为 max = 5
可以用va_list和vprintf来实现printf的功能,如下样例。
#include <stdio.h>
#include <stdarg.h>
void debug_log(char* str, ...){
va_list argc;
va_start(argc, str);
vprintf(str, argc);
va_end(argc);
}
int main(){
int a = 1;
debug_log("a is %d", 1);
return 0;
}
//输出结果为 a is 1。
有用的使用-宏定义debug日志
首先介绍一些宏定义的常量:
__FILE__:文件名
__FUNCTION__:函数名
__LINE__:所在的行数
有了这些之后就可以进行debug日志的输出,知道这条输出信息是在哪个文件的哪个函数的哪一行输出的,来快速确定输出的位置。
#include <stdio.h>
#include <stdarg.h>
void debug_log(char* str, ...){
va_list argc;
va_start(argc, str);
vprintf(str, argc);
va_end(argc);
}
#define DEBUG_LOG(str, argc...) debug_log("file is :%s func is:%s line is :%d "str"", __FILE__, __FUNCTION__, __LINE__, ##argc)
int main(){
int a = 1;
DEBUG_LOG("a is %d", 1);
return 0;
}
//输出结果为:file is :C:\Users\haimiao\Desktop\test.c func is:main line is :12 a is 1
其中##argc的作用代表着可变参数,##的作用是做拼接,因为可能argc为空,所以##当可变参数为空的时候将前面逗号吃掉。
当然上面的debug_log可以直接替换成printf,如下:
#include <stdio.h>
#include <stdarg.h>
#define DEBUG_LOG(str, argc...) printf("file is :%s func is:%s line is :%d "str"", __FILE__, __FUNCTION__, __LINE__, ##argc)
int main(){
int a = 1;
DEBUG_LOG("a is %d", 1);
return 0;
}