C 可变参数函数:如何指定给 va_arg 的类型 [英] C variadic function: How to specify which type to give to 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屋!