本来是想基于arm上实现printf函数,该函数参数类型不固定、个数也不固定,于是有点好奇,C语言是如何实现的。在看懂下面函数之前,必须了解一个问题,就是调用一个函数时,压入堆栈的数据是哪些排列的顺序如何。
在进程中,堆栈地址从高往低分配的。调用函数时,压入堆栈的数据排列格式如下:
- 最后一个可变参数
- 倒数第二个可变参数
- ...
- 第一个可变参数
- 固定参数(这里假设固定参数为一个)
- 函数返回地址
- 函数代码段
#include<stdio.h>
#include<stdarg.h>
int sum(int n, ...) //n表示可变参数的个数
{
int sum=0,temp=0,i=0;
va_list ap;
va_start(ap, n); //指向第一个可选参数
for(i = 0; i < n; i++)
{
temp = va_arg(ap,int); //取出类型为int可选参数的值,并且指向下一个可选参数
sum=sum+temp;
}
va_end(ap); //关闭,相当于把ap指针的值置为NULL
return sum;
}
int main()
{
printf("%d\n",sum(5,10,20,30,40,50));
printf("%d\n",sum(2,10,30));
}
程序运行效果图如下: