C语言可选性自变量(摘自C语言核心技术)

C语言允许定义自变量数量可变的函数,这称为variadic函数。这样的函数需要固定数目的强制性自变量(mandatory argument),后面是数量可变的可选性自变量。这样的函数必须有“至少一个”强制性自变量。可选性自变量的类型可能会改变,可选性自变量的数量可能由“强制性自变量的值”所决定,或者由“用来定义可选性自变量列表的特殊值”所决定。

C语言中,最有名的variadi函数范例是printf()和scanf()。这两个函数都有一个强制性自变量,也就是格式字符串;格式化字符串中的转换修饰符决定可选性自变量的类型和数量。

对于每一个强制的变量来说,函数头会显示一个适当的参数,像一般的函数声明一样。参数列表的规格是强制性参数在前(用逗号隔开),后面跟着一个逗号和省略符号(...),这个省略符号就代表可选性自变量。

variadic函数要存取可选性自变量时,必须通过一个类型为va_list的对象,它包含了自变量信息。这种类型的对象也称为“自变量指针”(argument pointer),它最少包含此堆栈中一个自变量的位置。可以使用这个自变量指针前移到下一个可选性自变量,这样的话,函数就可以存取所有的可选性自变量。va_list类型被定义在stdarg.h头文件中。

当编写支持“数量可变自变量”的函数时,必须用va_list类型定义自变量指针,以存取可选性自变量。在下面的讨论中,va_list对象被命名为argptr。可以用四个宏来处理此自变量指针,这些宏都定义在stdarg.h头文件中:

void va_start(va_list argptr, lastparam);

va_start宏使用第一个可选性自变量的位置来初始化argptr自变量指针。此宏的第二个自变量必须是“此函数最后一个有名称的参数”的名称。开始使用可选性自变量之前,你必须先调用此宏。

type va_arg(va_list argptr, type);

va_arg宏会取得目前argptr所引用的可选性自变量,也会将argptr前移到下一个自变量。va_arg宏的第二个自变量是“刚刚读入”自变量的类型。

void va_end(va_list argptr);

当不再需要自变量指针时,你必须调用va_end宏。若干想使用va_start或va_copy来重新初始化一个之前用过的自变量指针,也必须先调用va_end。

void va_copy(valist dest, va_list src);

va_copy宏使用目前的src来初始化自变量指针dest。然后就可以使用dest来存取可选性自变量列表,从src引用的位置开始。

  
    
1 #include < stdio.h >
2 #include < stdlib.h >
3 #include < stdarg.h >
4
5   void myprintf( const char * fmt, ...)
6 {
7 /*
8 * va_list 类型用于声明一个变量, 该变量将依次引用各参数.
9 * va_start 将变量初始化为指向第一个无名参数的指针.
10 * va_arg 该函数都将返回一个参数, 并将变量指向下一个参数.
11 */
12 va_list ap;
13 va_start(ap, fmt);
14 const char * p;
15 for ( p = fmt; * p; p ++ ) {
16 if ( * p == ' % ' ) {
17 switch ( *++ p) {
18 case ' d ' :
19 printf( " %d " , va_arg(ap, int ));
20 break ;
21 case ' f ' :
22 printf( " %f " , va_arg(ap, double ));
23 break ;
24 case ' s ' :
25 printf( " %s " , va_arg(ap, char * ));
26 break ;
27 default :
28 break ;
29 }
30 } else {
31 putchar( * p);
32 }
33 }
34 va_end(ap);
35 }
36   int main( int argc, char * argv[])
37 {
38 myprintf( " %s = %d / %f\ = %f\n " , " 100 / pi " , 100 , 3.1415926 , 100 / 3.1415926 );
39 getch();
40 return 0 ;
41 }

执行结果为,在控制台输出:

100 / pi = 100 / 3.141593 = 31.830989

你可能感兴趣的:(C语言)