C 可变参数函数:如何指定给 va_arg 的类型 [英] C variadic function: How to specify which type to give to va_arg

查看:32
本文介绍了C 可变参数函数:如何指定给 va_arg 的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 printf 之类的函数中,我们使用 stdarg.h 来处理可变参数.

In a function like printf, we use stdarg.h to handle the variadic parameters.

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.

We want to parse the format list (the first argument given to our variadic function) to track the types of the arguments specified in the format list then, call va_arg with the appropriate type.

我进行了第一个循环来解析格式列表,将说明符字母存储到一个数组中.所以我知道我们期望哪种类型以及有多少种.

I make a first loop to parse the format list, store the specifiers letters into an array. So I know which type we expect and how many there is.

例如:ft_like_printf("注意你的 %d %s\n", 6, "Spider pig");

specifiers_list = "ds"所以 d <=> int 和 s <=> char*(与 printf 相同的说明符)

specifiers_list = "ds" So d <=> int and s <=> char* (same specifiers as printf)

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

But how to code it dynamically? What is the syntax to call va_arg with differents types ?

我已阅读">THAT 我认为是我正在寻找的,不是吗?如果是,如何处理?包含枚举 + 联合的结构或包含联合 + 函数指针的结构的实际情况是什么?

I have read THIS and THAT which I think are what I'm looking for, aren't they ? If yes, what to do with it ? What are the real case scenarios of a struc containing an enum + union or struct containing an union + function pointer ?

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

To handle the different data types, I had started with this:

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

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

推荐答案

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

Types are not first-class citizens in C.

但是你需要关心的类型并不多:你可以安全地从 unsigned 转换为 signed,反之亦然, 也是如此char*void*,所以对于基本的 printf,你必须处理:

But there are not that many types you have to care about: you can safely cast from unsigned to signed and the other way around, same goes for char* and void*, so for a basic printf, you have to handle:

  • 字符
  • 简短
  • 内部
  • 浮动
  • 双重
  • 无效*

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:
            /* ... */
    }
}

然后你只需要创建一个查找表,为每个有效的格式说明符存储一个函数指针和一个t_type.

Then you just have to create a lookup table, storing both a function pointer and a t_type for each valid format specifier.

这篇关于C 可变参数函数:如何指定给 va_arg 的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆