C variadic函数:如何指定要赋予va_arg的类型

时间:2014-12-15 12:01:24

标签: c variadic-functions

在像printf这样的函数中,我们使用stdarg.h来处理可变参数。

void print(int args,...){
    va_list ap;
    va_start(ap, args);
    int i = 0;
    for(i=0; i<args; i++){
        printf("%d\n",va_arg(ap, int));
    }
    va_end(ap);
}

我们要解析格式列表(赋予我们的可变参数函数的第一个参数)以跟踪格式列表中指定的参数类型,然后使用适当的类型调用va_arg。

我创建第一个循环来解析格式列表,将说明符字母存储到数组中。 所以我知道我们期望的类型和数量。

ex:ft_like_printf("Watch your %d %s\n", 6, "Spider pig");

specifiers_list = "ds" 所以d&lt; =&gt; int和s&lt; =&gt; char *(与printf相同的说明符)

但如何编码动态?使用不同类型调用va_arg的语法是什么?

我已阅读THISTHAT,我认为这是我正在寻找的,不是吗? 如果是,那该怎么办?包含enum + union或包含union +函数指针的struct的struc的真实案例场景是什么?

为了处理不同的数据类型,我从这开始:

typedef struct s_flist
{
    char c;
    (*f)();
}              t_flist;

t_flist flist[] = 
    {
        { 's',  &putstr  },
        { 'i',  &put_number },
        { 'd',  &put_number }
    };

1 个答案:

答案 0 :(得分:1)

类型不是C中的一等公民。

但是你不必关心那么多类型:你可以安全地从unsigned投射到signed,反之亦然,char*和{{1所以对于基本的printf,你必须处理:

  • INT
  • 无效*

void*救援!

union

然后你只需创建一个查找表,为每个有效的格式说明符存储函数指针和typedef union { char as_char; short as_short; int as_int; long as_long; float as_float; double as_double; void* as_ptr; } t_value; typedef enum { CHAR_T, INT_T, /* It goes on */ ... } t_type; t_value get_value(va_list ap, t_type type) { /* You can't avoid this step, there is no way to iterate over types */ switch (type) { case T_CHAR: return va_arg(ap, char); case T_INT: /* ... */ } }