[英]C variadic function: How to specify which type to give to va_arg
In a function like printf, we use stdarg.h
to handle the variadic parameters. 在类似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);
}
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. 我们想解析格式列表(给可变参数函数的第一个参数),以跟踪格式列表中指定的参数类型,然后用适当的类型调用va_arg。
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.
所以我知道我们期望哪种类型,以及有多少种。
ex: ft_like_printf("Watch your %d %s\\n", 6, "Spider pig");
例如:
ft_like_printf("Watch your %d %s\\n", 6, "Spider pig");
specifiers_list = "ds"
So d <=> int and s <=> char* (same specifiers as printf) specifiers_list = "ds"
所以d <=> int和s <=> char *(与printf相同的说明符)
But how to code it dynamically ? 但是如何动态编码呢? What is the syntax to call va_arg with differents types ?
用differents类型调用va_arg的语法是什么?
I have read THIS and THAT which I think are what I'm looking for, aren't they ? 我已阅读本和THAT我认为是什么我要找的,不是吗? 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 }
};
Types are not first-class citizens in C. 类型不是C语言中的一等公民。
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: 但是,您不必担心很多类型:您可以安全地将类型从
unsigned
为signed
,反之亦然, char*
和void*
也是如此,因此对于基本的printf,您必须处理:
union
to the rescue ! 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:
/* ... */
}
}
Then you just have to create a lookup table, storing both a function pointer and a t_type
for each valid format specifier. 然后,您只需要创建一个查找表,
t_type
为每个有效格式说明符存储一个函数指针和一个t_type
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.