C语言 - 可变参数函数 va_list、va_start、va_arg、va_end
目录
一、_INTSIZEOF宏分析
二、可变参数函数介绍
1、va_list
2、va_start
3、va_arg
4、va_end
三、使用介绍
示例1:
示例2:
一、_INTSIZEOF宏分析
#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
功能:获取n按照4字节的整数倍对齐后的字节数
分析:
- (sizeof(n)+sizeof(int)-1) 相当于 sizeof(n) + 3
- ~(sizeof(int) - 1) ) 相当于 ~(3),即:二进制 11111100
由此可知, ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) 相当于 (sizeof(n) + 3) / 4 *4,因此 _INTSIZEOF(n) 作用是将n的字节数按照 sizeof(int) 的整数倍进行对齐。
二、可变参数函数介绍
头文件:stdarg.h
1、va_list
va_list ap; //ap指针
功能:va_list 表示可变参数列表类型,实际上就是一个char指针
2、va_start
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
功能:va_start用于获取函数参数列表中可变参数的首指针(获取函数可变参数列表)
当调用va_start(ap, param1) 后,ap指针指向 param1后的第一个可变参数。
3、va_arg
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
功能:va_arg用于获取当前ap所指的可变参数,并将ap指针移向下一可变参数
在执行va_start后ap指针指向了第一个可变参数,再调用va_arg返回当前ap指向的可变参数,并将ap指向下一个可变参数
4、va_end
#define va_end(ap) ( ap = (va_list)0 )
功能:清空va_list可变参数列表
三、使用介绍
示例1:
#define BUF_SIZE 16
void my_printf(const char *fmt, ...)
{
char buf[BUF_SIZE];
va_list ap; //ap为指针
va_start(ap, fmt); //ap指向 fmt 后的第一个可变参数首地址
vsnprintf(buf, BUF_SIZE, fmt, ap); //buf存放 fmt格式化的字符串
char *p = va_arg(ap, char *); //调用va_arg取第一个可变参数值,并将ap指针指向下一个可变参数地址
va_end(ap);
}
示例2:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h> //头文件
/* */
int fun1(int num, ...)
{
int i = 0;
va_list ap; //ap是个指针
va_start(ap, num); //ap指针指向a后的第一个可变参数首地址
/* 打印所有可变参数 */
for (i = 0; i < num; i++)
{
printf("param%d:[%d]\n", i, va_arg(ap, int));
}
va_end(ap); //清理ap
return num;
}
int main()
{
fun1(2, 8, 9); // 2个参数,分别是8和9
return 0;
}