美文网首页
C/C++可变参数机制

C/C++可变参数机制

作者: 劝分不劝和 | 来源:发表于2018-03-25 13:23 被阅读0次

在写一个函数时,经常会有实现一个参数未知或不是常数的函数的需求。printf就是这样的一个函数,在 Section 9.11中有详细描述。接下来的例子将想你展示如何声明一个这样的函数。

int f(int, ... ) {
        .
        .
        .
}

int g() {
        f(1,2,3);
}
//Example 9.5

为了得到被调用的函数的参数, <stdarg.h>头文件中函数的声明必须要被包括。这就引入了一个新类型va_list和三个对这个类型的对象的函数,它们是va_start, va_arg, 和va_end

在获取一个变量参数列表之前,va_start一定要被调用,它被定义成

#include <stdarg.h>
void va_start(va_list ap, parmN);

va_start 宏初始了ap为 接下来的函数va_argva_end所用。va_start的第二个参数parmN是作为标识符命名了函数定义(在...前面那个)中变量参数表中最右边参数。标识符parmN不能被声明成register的存储类或作为一个函数或数组类型。

一旦初始化了,提供的这些参数就可以在接下来被va_arg 宏所使用。这很奇怪,因为返回的类型是被宏的一个参数所定义的。注意这不可能由一个真正的函数去实现,而只能是一个宏。它被定义成

#include <stdarg.h>
type va_arg(va_list ap, type);

每次对这个宏的调用都会提取参数列表中的下一个参数作为一个特定类型的值。va_list 参数必须是一个被va_start初始化的参数。如果接下来的参数不是特定的那种类型,那么这成了一个未定义的行为。在这里要注意避免可能由于数值类型转换而导致的问题。用char或者short作为va_arg的第二个参数总是错误的:这些类型总是会提升到signed intunsigned int中的一个,以及float 会转换成double。注意是执行时才定义是否对象声明为类型char, unsigned char, unsigned short ,无符号的那些位阈会提升至unsigned int,还是复杂化va_arg。这可能是一些预期以外的微妙的事情发生的地方;时间会说明一切。

va_arg被调用却没有更多的参数时,这种行为也是不被定义的。

这里的type(类型)参数的类型名,必须可以简单地用添加一个*来转换成一个指向一个对象的指针 。简单类型如char就可以(因为char *就是一个指向字符对象的指针),但是字符数组就不行(char []不能用添加*的方式转换成‘指向字符数组的指针’)。好在,数组还是很好处理的--只要记住数组名作为函数调用实参的时候本身就会转换成一个指针就可以了。对于一个'字符数组'参数类型而言,正确的type将会是char *

当所有参数都被处理了的时候,va_end函数应该被调用,这将会防止va_list里的那些已经被用过的参数再次呈递上去。如果va_end没有被使用,这种行为是未定义的。

在调用va_end以后,整个参数列表可以用再调用va_start 的方法被重新遍历。va_end函数被声明为

#include <stdarg.h>
void va_end(va list ap);

接下来的例子展示了va_start,va_arg, 和va_end在实现一个返回最大整型参数的函数里的用法

#include <stdarg.h>
#include <stdio.h>

int maxof(int, ...) ;
void f(void);

main(){
        f();
        exit(EXIT_SUCCESS);
}

int maxof(int n_args, ...){
        register int i;
        int max, a;
        va_list ap;

        va_start(ap, n_args);
        max = va_arg(ap, int);
        for(i = 2; i <= n_args; i++) {
                if((a = va_arg(ap, int)) > max)
                        max = a;
        }

        va_end(ap);
        return max;
}

void f(void) {
        int i = 5;
        int j[256];
        j[42] = 24;
        printf("%d\n",maxof(3, i, j[42], 0));
}
//Example 9.6

阅读原文

相关文章

  • C/C++可变参数机制

    在写一个函数时,经常会有实现一个参数未知或不是常数的函数的需求。printf就是这样的一个函数,在 Section...

  • C/C++可变参数

    C/C++中支持传递可变参数,即不定参数,例如: 那么如何拿到不定参数,需要借助va_list类型,包含在cstd...

  • c++函数可变参数

  • C++可变参数宏

    格式 C99开始支持如下可变参数宏 GCC同样支持如下格式 连接符,在展开如将每一个arg展开了arg加上逗号,如...

  • C++ 泛型编程(一) —— 可变参数模板

    可变参数模板函数 可变参数模板是 C++ 11 中引入的一个新特性,它允许我们定义一个可以接受可变数目参数的模板函...

  • day14

    可变和不可变参数 不可变类型: 类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a...

  • *args和**kwargs的用法

    可变位置参数*args *args为一个列表,用于向函数传递数量可变的参数,我觉得相当于Java和C++中的重载,...

  • C++语言-this关键字、友元函数友元类、操作符重载

    1、C++中的可变参数 2、C++ static关键字 static关键小结:1、绝大多数和Java一样,静态的函...

  • C++语言之this原理与友元函数友元类

    1.C++可变参数。java 可变参数 int...C++ 可变参数 ... 需要引入头文件 stdarg.h头文...

  • C++可变参数模板

    可变参数模板 原文链接: http://blog.csdn.net/xiaohu2022/article/deta...

网友评论

      本文标题:C/C++可变参数机制

      本文链接:https://www.haomeiwen.com/subject/srayqftx.html