• 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

  • 相关阅读:
    再次梳理css3动画部分知识
    node搭环境
    微信小程序可用的第三方库
    省市区三级联动下拉框效果分析
    jq回到顶部效果分析
    jq案例中遇到的知识点总结(会飞的小鸟和三级联动)
    js正则表达式大全
    js中表达式 >>> 0 浅析
    为什么js中要用void 0 代替undefined
    npm install、npm install --save、npm install --save --dev、npm install -S、npm install -D的区别
  • 原文地址:https://www.cnblogs.com/arci/p/1972208.html
Copyright © 2020-2023  润新知