C语言中的可变参数算是一个比较少用的知识点,scanf/printf输入输出函数都使用到了可变参数。
int printf(const char * format, ...);
int scanf(const char * format, ...); // ...:表示参数不固定,是可变的
那么问题来了,如果我们自定义一个函数,函数参数可变,怎么才能把参数取出来呢?
①、添加 #include <stdarg.h>头文件
②、定义一个参数指针
③、va_start:初始化参数指针,指向第一个参数
④、va_arg:获取参数指针中的参数(注:参数只能获取一次)
⑤、va_end:当不再需要使用参数指针时,必须调用宏 va_end。
以上是自定义可变参数函数的基本步骤。
例子:
#include <stdarg.h> //添加头文件
#include <stdio.h>
void text(int a, ...) //...表示参数可变
{
va_list ap; //定义一个参数指针ap
int val1, val2;
va_start(ap, a); //让参数指针指向第一个参数
val1 = va_arg(ap, int); //以int类型来获取可变参数的第一个参数
printf("%d\n", val1);
val2 = va_arg(ap, int); //以int类型来获取可变参数的第二个参数
printf("%d\n", val2);
};
void main(void)
{
text('a', 123, 456);
}
输出结果:
123
456
-------------------------------------------------------------------------------------------------------------------------------
我用函数的可变参数解决了一个比较棘手的问题,学过单片机的同学都知道在使用一个串口打印数据时可以将printf重定向。重定向后可以直接使用printf函数将数据从串口1中发送出来。如果单片机使用多个串口时,其他串口我也想用printf相似的调用方法(比如:Usart_prinf("%s\r\n","123456"))我们是无法实现的,这里就需要自己编写一个类似printf的打印函数。
以下是我自己编写的串口2打印函数(给WIFI发送AT指令):
void Wifi_Send(const char *format, ...)
{
char *p = NULL;
va_list ap; //定义一个可变参数链表
va_start(ap, format); //准备访问可变参数
while(*format != '\0')
{
if(*format != '%')
{
USART2_Send_Byte(*format);
format++;
continue;
}
else
{
format++;
switch(*format)
{
case 's': p = va_arg(ap, char *); //只能识别%s
printf("识别到的数据: %s\r\n", p);
while(*p) //这一步可以再进行封装
{
USART2_Send_Byte(*p);
p++;
}
break;
default:
USART2_Send_Byte(*format);
break;
}
format++;
}
}
va_end(ap);
}
本人是一名在校学生,如果有错误的地方可以评论指正。
希望我的这片文章可以帮助到大家!!!