zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    常见寻找OEP脱壳的方法
    Windows内核原理系列01
    HDU 1025 Constructing Roads In JGShining's Kingdom
    HDU 1024 Max Sum Plus Plus
    HDU 1003 Max Sum
    HDU 1019 Least Common Multiple
    HDU 1018 Big Number
    HDU 1014 Uniform Generator
    HDU 1012 u Calculate e
    HDU 1005 Number Sequence
  • 原文地址:https://www.cnblogs.com/arci/p/1972208.html
Copyright © 2011-2022 走看看