va_arg, va_end, va_start
访问变量参数列表。
type va_arg(
va_list arg_ptr,
type
);
void va_end(
va_list arg_ptr
);
void va_start(
va_list arg_ptr,
prev_param
); // (ANSI version)
void va_start(
arg_ptr
); // (Pre-ANSI-standardization version)
参数
type
要检索的参数的类型。arg_ptr
参数列表的指针。prev_param
前面的第一个可选参数 (仅 ANSI) 的参数。
返回值
va_arg返回当前参数。 va_start和va_end不返回值。
备注
va_arg, va_end,和va_start宏提供访问函数的参数时该函数采用的参数数目可变的可移植的方式。有两个版本的宏: 在 STDARG 中定义的宏。H 符合 ANSI C 标准。VARARGS 中定义的宏。H 已过时,保持向后兼容性。它们被设计以使用 ANSI 标准化之前。
这些宏,将假定该函数采用固定的数量的必选参数后, 跟可选的参数数目可变。必选的参数作为普通函数参数的声明,并且可以通过参数名来访问。可选参数被通过 STDARG 中的宏。H 或 VARARGS。H,从而将指针设置为第一个可选参数在参数列表中,从列表中,检索参数并参数处理完成时,重置指针。
ANSI C 标准,定义的宏在 STDARG 中。H) 的用法如下:
va_start设置arg_ptr第一个参数列表中的可选参数传递给函数。该参数arg_ptr必须具有va_list类型。该参数prev_param是前面的第一个可选参数,参数列表中所需的参数的名称。如果prev_param与寄存器存储类,该宏的行为未定义声明。va_start之前,必须使用va_arg用于第一次。
va_arg检索一个值的type位置从arg_ptr和增量arg_ptr指向下一个参数的列表中,使用的大小type来确定下一个参数的开始位置。va_arg可以是用于检索参数列表中任意数量的函数内的时间。
已检索所有参数后, va_end指针,将重置空。
C++ 说明 |
---|
VARARGS 中定义的宏。不建议使用和存在只是为了向后兼容性。使用 STDARGS 中定义的宏。除非您使用的代码之前的 ANSI 标准 h。 |
使用编译时/clr(公共语言运行时编译),使用这些宏的程序可能会生成意外的结果,由于本机和公共语言运行库类型的系统之间的差异。此程序,请考虑:
#include <stdio.h>
#include <stdarg.h>
void testit ( int i, ...)
{
va_list argptr;
va_start(argptr, i);
if ( i == 0 ) {
int n = va_arg( argptr, int );
printf( "%d\n", n );
} else {
char *s = va_arg( argptr, char* );
printf( "%s\n", s);
}
}
int main()
{
testit( 0, 0xFFFFFFFF ); // 1st problem: 0xffffffff is not an int
testit( 1, NULL ); // 2nd problem: NULL is not a char*
}
请注意, testit要求应是其第二个参数int或char*。正在传递的参数是用 0xffffffff ( unsigned int、 不int) 和NULL (实际int、 不char*)。在编译为本机代码,该程序将生成输出
-1
(null)
但是,使用编译时/clr:pure,类型不匹配会导致程序生成异常。该解决方案是使用显式强制转换:
int main()
{
testit( 0, (int)0xFFFFFFFF ); // cast unsigned to int
testit( 1, (char*)NULL ); // cast int to char*
}
要求
标题: <stdio.h> 和 <stdarg.h>
旧的标头: <varargs.h>
库
所有版本的 C 运行时库。
示例
// crt_va.c
/* The program below illustrates passing a variable
* number of arguments using the following macros:
* va_start va_arg va_end
* va_list
*/
#include <stdio.h>
#include <stdarg.h>
int average( int first, ... );
int main( void )
{
/* Call with 3 integers (-1 is used as terminator). */
printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );
/* Call with 4 integers. */
printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );
/* Call with just -1 terminator. */
printf( "Average is: %d\n", average( -1 ) );
}
/* Returns the average of a variable list of integers. */
int average( int first, ... )
{
int count = 0, sum = 0, i = first;
va_list marker;
va_start( marker, first ); /* Initialize variable arguments. */
while( i != -1 )
{
sum += i;
count++;
i = va_arg( marker, int);
}
va_end( marker ); /* Reset variable arguments. */
return( sum ? (sum / count) : 0 );
}
Output
Average is: 3
Average is: 8
Average is: 0