本文章介绍一下C语言中一些跟可变参数相关的宏及其用法
C语言中有很多的带有可变参数的函数,例如printf函数,它的定义其实是类似这样子的
void printf(char *format,...);
其中format为格式化的数据,后面三个点是占位符,用来表示可变参数列表
如果我们想自定义带有可变参数的函数的话,format(格式化数据)必须是函数中参数列表的最后一个固定参数,接下来介绍几个跟可变参数列表有关的宏
宏和函数不同,宏在预处理阶段就会被展开,其实现由编译器提供,通常会包含在相应的标准库头文件中。
#include
va_list args;
va_list数据类型代表可变参数列表,我们可以通过这个数据类型,来使用可变参数列表或者访问可变参数列表中的每一个元素,这个类型一般作为其他函数的参数来使用.
void va_start(va_list ap, last_arg);
用作初始化可变参数列表
其中 ap 是一个 va_list对象,表示可变参数列表
last_arg 是带有可变参数的函数中的最后一个固定参数
type va_arg(va_list ap, type);
用来访问可变参数列表中的某一个参数,并将可变参数列表的指针往后面移动一位
具体的使用例子:
获取可变参数列表中第一个参数,参数类型为int
int num = va_arg(args,int);
获取可变参数列表中第一个参数,参数类型为char *
char *str = va_arg(args,char*);
void va_end(va_list ap);
结束对可变参数的访问
void my_printf(char *format, ...) {
va_list args;
va_start(args, format); // 初始化可变参数列表
char *ptr = format;
while (*ptr != '\0') {
if (*ptr == '%') {
ptr++; // 移动到格式字符
if (*ptr == 'd') {
int num = va_arg(args, int); // 获取 int 类型参数
printf("%d", num);
} else if (*ptr == 's') {
char *str = va_arg(args, char*); // 获取 char* 类型参数
printf("%s", str);
} else {
printf("Invalid format specifier!"); // 不支持的格式符号
}
} else {
putchar(*ptr); // 普通字符直接输出
}
ptr++;
}
va_end(args); // 结束可变参数列表
}
这个是一个函数,而不是一个宏
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
str 指定将格式化数据放入的字符串
size 缓冲区大小
format 格式化数据
ap 可变参数列表
这个函数和snprintf函数非常类似,都是把格式化的数据放入指定长度的字符串中,但是区别是snprintf函数的最后一个参数是三个点的可变参数列表(. . .),而vsnprintf函数的最后一个参数是 va_list类型的可变参数列表
具体使用方式
#include
#include
void formatString(char *buffer, size_t size, const char *format, ...) {
va_list args;
va_start(args, format);
vsnprintf(buffer, size, format, args);
va_end(args);
}
int main() {
char buffer[20];
int num = 42;
formatString(buffer, sizeof(buffer), "The answer is: %d", num);
printf("Buffer content: %s\n", buffer);
return 0;
}
如果我们想在C语言中定义有可变参数的宏的话,就需要使用这个宏
//最简单的定义
#define my_print1(...) printf(__VA_ARGS__)
//搭配va_list的format使用
#define my_print2(format, ...) printf(format, __VA_ARGS__)
#define my_print3(format, ...) printf(format, ##__VA_ARGS__)
如果参数列表为空的话,就需要在 __VA_ARGS_前面加上 ##,这样就会去掉前面的逗号,防止编译错误.
#include
#define my_print1(...) printf(__VA_ARGS__)
int main()
{
int a=1,b=2;
my_print1("%d%d",a,b);
}