我无法在标准中找到与它们使用的C常见问题解答(Question 1.22)相关的任何通用函数指针:
typedef int (*funcptr)(); /* generic function pointer */
typedef funcptr (*ptrfuncptr)(); /* ptr to fcn returning g.f.p. */
在状态机上玩些我的方法:
#include <stdio.h>
#define STM(x) (stm)x
typedef void (*stm)(void);
typedef stm (*pstm)(void *);
stm start(void *),
state1(void *),
state2(void *),
state3(void *),
stop(void *);
static int exit_state(int state)
{
char str[2];
int c;
printf("Exit state %d? ", state);
if (fgets(str, sizeof str, stdin)) {
while (((c = fgetc(stdin)) != '\n') && (c != EOF));
return (str[0] == 'y') || (str[0] == 'Y');
}
return 0;
}
static void state_machine(pstm pstart, void *data)
{
pstm state = pstart;
while (state != NULL) {
state = (pstm)(*state)(data);
}
}
stm start(void *data)
{
puts("Starting state machine");
*(char **)data = "Comes from start";
return STM(state1);
}
stm state1(void *data)
{
puts(*(char **)data);
puts("State 1");
if (!exit_state(1)) {
return STM(state1);
}
*(char **)data = "Comes from state 1";
return STM(state2);
}
stm state2(void *data)
{
puts(*(char **)data);
puts("State 2");
if (!exit_state(2)) {
return STM(state2);
}
*(char **)data = "Comes from state 2";
return STM(state3);
}
stm state3(void *data)
{
puts(*(char **)data);
puts("State 3");
if (!exit_state(3)) {
return STM(state1);
}
return STM(stop);
}
stm stop(void *data)
{
(void)data;
puts("Stopping state machine");
return NULL;
}
int main(void)
{
char *data;
state_machine(start, &data);
return 0;
}
我的问题是:有效使用
typedef void (*stm)(void);
作为功能的通用指针?
从我看来,在进行演员表转换之前,我们可以使用任何类型的原型,即
typedef long double (*stm)(unsigned long long);
也是有效的
我的假设正确吗?
答案 0 :(得分:4)
引用来自:http://c-faq.com/ptrs/generic.html
保证,但是,所有函数指针都可以 相互转换,只要它们可以转换回适当的 在致电之前输入。因此,您可以选择任何功能类型 (通常是int()()或void()(),即指向函数的指针 未指定的参数返回int或void)作为泛型函数 指针。当您需要放置对象和函数指针的地方 可互换的解决方案是使用void *的并集 以及通用函数指针(无论您选择哪种类型)。
所以,是的,使用b
或typedef void (*stm)(void);
作为函数的通用指针。
链接中突出显示的文本的引用:
ISO秒6.1.2.5,第二节6.2.2.3,第二节6.3.4 基本原理3.2.2.3 H&S秒5.3.3页12
编辑 :(从其他答案中添加更多详细信息)
n1570草案中C11的引用是6.3转换/ 6.3.2.3指针§8:
指向一种类型的函数的指针可以转换为指向 另一种功能并再次返回;结果应进行比较 等于原始指针。如果使用转换后的指针来调用 一个类型与所引用类型不兼容的函数, 行为是不确定的。