C variadic函数:如何指定要赋予va_arg的类型
在像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。
我创建了第一个循环来解析格式列表,将说明符字母存储到数组中。 所以我知道我们期望的类型和数量。
例如: ft_like_printf("Watch your %d %s\n", 6, "Spider pig");
specifiers_list = "ds"
所以d int和s char *(与printf相同的说明符)
但是如何动态编码呢? 使用不同类型调用va_arg的语法是什么?
我已经读过这个和我认为我正在寻找的东西,不是吗? 如果是,那该怎么办? 包含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 } };
C中的类型不是一等公民。
但是你不必关心那么多类型:你可以安全地从unsigned
为signed
,反之亦然,同样适用于char*
和void*
,所以对于基本的printf,你必须处理:
- 烧焦
- 短
- INT
- 长
- 浮动
- 双
- 无效*
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
。