//STM32平台
#include <stdarg.h>
void test(int, ...);
void test(int num_args, ...)
{
double V1,V2,V3,V4;
va_list ap;
va_start(ap, num_args);
V1 = num_args;//va_arg(ap, int);
V2 = va_arg(ap, double);
V3 = va_arg(ap, char);//编译被警告,char被自动提升为int
V4 = va_arg(ap, short);//编译被警告,char被自动提升为int
va_end(ap);
}
int main(void)
{
int v1=0x1A;
double v2=0x2A2A2B2B2C2C;
char v3=0x3A;
short v4=0x4A4A;
test(v1,v2,v3,v4);
}
分析:
在调用可变参数的函数时,例如上面的例子test函数,必须在第一个参数中指明后续参数的个数及类型(例如系统自带的printf函数),否则,在test函数内部无法解析出参数,除非程序员在编程前已经约定好参数的数量和类型。在这个例子中,我们已经约定好了test的参数数量为4,类型依次为int、double、char、short,所以在test函数内部我们才能够给va_arg函数的第二参数依次赋值。
需要注意的是,va_arg函数的第二参数只能是sizeof(int)的整数倍,否则,会被编译器警告,并被编译器自动提升为可容纳该类型的最小”sizeof(int)的整数倍”,如u8/u16都会被自动提升为int;又如:6 bytes的结构体,会被自动提升可容纳6 bytes的double型,即2*sizeof(int)=8 bytes。这一特性出现的原因是,实参入栈时,都是按照int的整数倍入栈的(例如,char v3类型的实参入栈时,会在栈中占据int类型的空间),所以在子函数中,从栈中取出参数,也得按int的整数倍取出。