对于C语言,怎样编写参数数目可变的函数?
你可以利用(stdarg.h)头文件,它所定义的一些宏可以让你处理数目可变的参数。
注意:这些宏以前包含在名为(varargs.h)或类似的一个头文件中。你的编译程序中可能还有这样一个文件,也可能没有;即使现在有,下一个版本中可能就没有了。因此,还是使用(stadrg.h)为好。
如果对传递给c函数的参数不加约束,就没有一种可移植的方式让c函数知道它的参数的数目和类型。如果一个c函数的参数数目不定(或类型不定),就需要引入某种规则来约束它的参数。例如,printf()函数的第一个参数是一个字符串,它将指示其后都是一些什么样的参数:
printf(" Hello, world! \n" ); /* no more arguments */
printf("%s\n" , "Hello, world!"); /* one more string argument */
printf("%s, %s\n" , "Hello" , "world!"); /* two more string arguments */
printf("%s, %d\n", "Hello", 42); /* one string, one int */
例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);
}
注意:这些宏以前包含在名为(varargs.h)或类似的一个头文件中。你的编译程序中可能还有这样一个文件,也可能没有;即使现在有,下一个版本中可能就没有了。因此,还是使用(stadrg.h)为好。
如果对传递给c函数的参数不加约束,就没有一种可移植的方式让c函数知道它的参数的数目和类型。如果一个c函数的参数数目不定(或类型不定),就需要引入某种规则来约束它的参数。例如,printf()函数的第一个参数是一个字符串,它将指示其后都是一些什么样的参数:
printf(" Hello, world! \n" ); /* no more arguments */
printf("%s\n" , "Hello, world!"); /* one more string argument */
printf("%s, %s\n" , "Hello" , "world!"); /* two more string arguments */
printf("%s, %d\n", "Hello", 42); /* one string, one int */
例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);
}