你可以利用(stdarg.h)头文件,它所定义的一些宏可以让你处理数目可变的参数。
注意:这些宏以前包含在名为(varargs.h)或类似的一个头文件中。你的编译程序中可能还有这样一个文件,也可能没有;即使现在有,下一个版本中可能就没有了。因此,还是使用(stadrg.h)为好。
如果对传递给c函数的参数不加约束,就没有一种可移植的方式让c函数知道它的参数的数目和类型。如果一个c函数的参数数目不定(或类型不定),就需要引入某种规则来约束它的参数。例如,printf()函数的第一个参数是一个字符串,它将指示其后都是一些什么样的参数:
例12.3给出了一个简单的类似printf()的函数,它的第一个参数是格式字符串,根据该字符串可以确定其余参数的数目和类型。与真正的printf()函数一样,如果格式字符串和其余参数不匹配,那么结果是没有定义的,你无法知道程序此后将做些什么(但很可能是一些糟糕的事情)。
例12.3一个简单的类似printf()的函数
# include <stdio. h>
# include <stdlib. h>
# include <string. h>
# include <stdarg. h>
static char * int2str (int n)
{
int minus = (n < 0) ;
static char buf[32];
char * p = &buf[3l];
if (minus)
n = —n;
*P = '\0',
do {
*---p = '0'+n%10;
n/=10;
} while (n>0);
if (minus)
*- - p = '-';
return p;
}
/*
* This is a simple printf-like function that handles only
* the format specifiers %%, %s, and %d.
*/
void simplePrintf(const char * format, . . . )
{
va_list ap; /* ap is our argument pointer. */
int i;
char * s ;
/*
* Initialize ap to start with the argument
* after "format"
*/
va_start(ap, format);
for (; * format; format + + ) {
if (* format !='%'){
putcharC * format);
continue;
}
switch ( * ++format) {
case 's' :
/* Get next argument (a char * ) */
s = va_arg(ap, char * );
fputs(s, stdout);
break;
case 'd':/* Get next argument (an int) */
i = va_arg(ap, int);
s = int2str(i) ;
fputs(s, stdout) ;
break s
case ' \0' : format---;
breaks
default :putchar ( * format) ;
break;
}
}
/* Clean up varying arguments before returning */
va_end(ap);
}
void main()
{
simplePrintK "The %s tax rate is %d%%. \n" , "sales", 6);
}