功能和状态机的通用指针

时间:2019-05-21 15:17:22

标签: c function-pointers state-machine

我无法在标准中找到与它们使用的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);

也是有效的

我的假设正确吗?

1 个答案:

答案 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:

  

指向一种类型的函数的指针可以转换为指向   另一种功能并再次返回;结果应进行比较   等于原始指针。如果使用转换后的指针来调用   一个类型与所引用类型不兼容的函数,   行为是不确定的。