使用相同的指针指向具有不同参数的函数
Point to functions with different arguments using the same pointer
我正在尝试为给定的输入构建解析器,有 8 个可能的命令。所以我想与其使用像这样的 case switch
块的丑陋技术:
switch(command)
case cmd1:
.... /*call a function that do cmd1*/
case cmd2
..../*call a function that do cmd2*/
我将在头文件中定义一个结构数组,每个结构都包含函数的名称和一个指向函数的指针:
typedef struct command_info
{
char *name;
void (*func)(int)
};
command_info command_table[] = {{"func1", &func1}, {"func2", &func2} }
这样我就可以切换到更优雅的:
int i;
for(i = 0; i < COMMAND_TABLE_LENGTH; i++)
if(!strcmp(command_table[i].name, command))
command_table[i].func(2);
我唯一的问题是,函数有不同的参数(所有 return 无效)。这对我来说不是问题,因为我可以检查函数是否是 func1
或 func2
搜索一个 int 参数,如果它是 func3
或 func4
搜索两个(仍然比 case switch
更紧凑)。但是函数指针仅指向具有特定类型和参数数量的函数。如何制作一个可以指向任何函数的通用指针?
But the function pointer only points to a function with a certain type and amount of arguments.
How can I make a universal pointer that can point to any function?
在OP的有限情况下,使用void (*func)()
。
任何函数指针都可以通过类型转换转换为另一个函数指针并保留等效的函数地址。
int (*foo)(int) = (int (*)(int)) sqrt;
double (*sq)(double) = (double (*)(double)) foo;
printf("%f\n", sq(2)); // prints 1.414214
函数指针不需要提供函数参数签名。
// No parameter info
// vv
int (*foo)() = (int (*)()) sqrt;
OP 具有 "functions have different parameters (all return void)",因此在 OP 的情况下,代码可以使用 void (*func)()
的有限通用函数指针并丢失参数检查。
typedef struct {
char *name; // suggest const char *name
void (*func)(); // no parameter info nor checking
} command_info;
char buf[100];
// void setbuf(FILE * restrict stream, char * restrict buf);
command_info fred = { "my_setbuf", setbuf };
// Both compile, 2nd is UB.
fred.func(stdin, buf); // No parameter checking.
fred.func(0); // No parameter checking.
代码在调用 .funf()
时也会产生一个微妙的问题:排名低于 int/unsigned
的参数在传递给函数之前与 float
参数一样被提升。最好确保参数不是 char, float, short, _Bool
等,以避免兼容签名问题。
void *
是一个通用的 object 指针。编码 function 指针可能不够。所以它不是一个可移植的候选者。函数指针的大小大于 sizeof(void*)
.
的情况并不少见
我正在尝试为给定的输入构建解析器,有 8 个可能的命令。所以我想与其使用像这样的 case switch
块的丑陋技术:
switch(command)
case cmd1:
.... /*call a function that do cmd1*/
case cmd2
..../*call a function that do cmd2*/
我将在头文件中定义一个结构数组,每个结构都包含函数的名称和一个指向函数的指针:
typedef struct command_info
{
char *name;
void (*func)(int)
};
command_info command_table[] = {{"func1", &func1}, {"func2", &func2} }
这样我就可以切换到更优雅的:
int i;
for(i = 0; i < COMMAND_TABLE_LENGTH; i++)
if(!strcmp(command_table[i].name, command))
command_table[i].func(2);
我唯一的问题是,函数有不同的参数(所有 return 无效)。这对我来说不是问题,因为我可以检查函数是否是 func1
或 func2
搜索一个 int 参数,如果它是 func3
或 func4
搜索两个(仍然比 case switch
更紧凑)。但是函数指针仅指向具有特定类型和参数数量的函数。如何制作一个可以指向任何函数的通用指针?
But the function pointer only points to a function with a certain type and amount of arguments.
How can I make a universal pointer that can point to any function?
在OP的有限情况下,使用void (*func)()
。
任何函数指针都可以通过类型转换转换为另一个函数指针并保留等效的函数地址。
int (*foo)(int) = (int (*)(int)) sqrt;
double (*sq)(double) = (double (*)(double)) foo;
printf("%f\n", sq(2)); // prints 1.414214
函数指针不需要提供函数参数签名。
// No parameter info
// vv
int (*foo)() = (int (*)()) sqrt;
OP 具有 "functions have different parameters (all return void)",因此在 OP 的情况下,代码可以使用 void (*func)()
的有限通用函数指针并丢失参数检查。
typedef struct {
char *name; // suggest const char *name
void (*func)(); // no parameter info nor checking
} command_info;
char buf[100];
// void setbuf(FILE * restrict stream, char * restrict buf);
command_info fred = { "my_setbuf", setbuf };
// Both compile, 2nd is UB.
fred.func(stdin, buf); // No parameter checking.
fred.func(0); // No parameter checking.
代码在调用 .funf()
时也会产生一个微妙的问题:排名低于 int/unsigned
的参数在传递给函数之前与 float
参数一样被提升。最好确保参数不是 char, float, short, _Bool
等,以避免兼容签名问题。
void *
是一个通用的 object 指针。编码 function 指针可能不够。所以它不是一个可移植的候选者。函数指针的大小大于 sizeof(void*)
.