有时候形式参数不确定,ANSI C采用可变参数列表的形式来实现这种函数,在stdarg.h中包括三个宏:va_list va_start (va_list,pre_arg)
va_arg(va_list,type) va_end(va_list),作用分别是:建立一个指针指向函数的最后一个参数;取出type类型的下一个参数,并将va_list类型的变量指向下一个变量,va_end结束可变函数.
以简单的printf函数为例:
void printf(char *fmt)
{
int d;
char buf[10];
char ch;
va_list ap;//建立指针ap
va_start(ap,fmt)//将ap指向fmt的下一个参数,fmt即输出的格式字符串
while(*fmt)//如果格式字符串没有到达‘/0’
{
if(*fmt!='%')//如果是%格式串之前的字符串常量,则输出
{
putchar(*fmt++);
continue;//结束这次if
}
switch(*fmt)//如果到达%格式输出,如%d等,这里做了简化,没有考虑在%和d之间的- + 等输出限定字符
{
case 'd'://如果是输出整数
d = va_arg(ap,int);//利用va_arg宏取出现在的ap指向的参数的值,并指向int类型后的下一个参数
itoa(d,buf,10);//将整数转换为字符串,一般这个函数在stdlib.h里,gcc好像只有atoi,自己写了
puts(buf);//输出整数
break;
case 'c'://输出字符
ch = va_arg(ap,int)//注意int,因为可变参数默认使用类型提升,所以char要写成int类型
putchar(ch);
break;
case 's'://输出字符串
s = va_arg(ap,char *);
puts(s);
break;
default:
break;
}
fmt++;//指向格式串的下一个字符
}
va_end(cp);
}