首页 > 解决方案 > 如何让函数在 C 中返回自己的类型?

问题描述

x = x();TL;DR 如果在 C 中有效,x 的类型应该是什么?


整个故事:

我正在开发一个具有多个场景的简单游戏。起初我的代码看起来像这样:

enum {kSCENE_A, kSCENE_B} ecene = kSCENE_A;
int main() {
    while(1) {
        switch(scene) {
          case kSCENE_A:
            // Renders scene a
            // And possibly modifies `scene`
            break;
          case kSCENE_B:
            // Renders scene b
            // And possibly modifies `scene`
            break;
        }
    }
}

但是这个main函数太冗长了。我将渲染部分提取到不同的函数中,但switch仍然使代码难看。scene_map我为此定义了一个:

typedef enum {
    kSCENE_A,
    kSCENE_B,

    kN_SCENES
} Scene;
Scene RenderSceneA();
Scene RenderSceneB();
int main() {
    Scene scene = kSCENE_A;
    Scene (*scene_map[kN_SCENES])();
    scene_map[kSCENE_A] = SceneA;
    scene_map[kSCENE_B] = SceneB;
    while(1) scene = scene_map[scene]();
}

但我想知道在 C 中是否可以用这种方式或类似的方式编写代码:

SomeType RenderSceneA();
SomeType RenderSceneB();
int main() {
    SomeType scene = RenderSceneA;
    while(1) scene = scene();
}

那么 SomeType 应该是什么类型,或者我只能void *用于它?如果后者是真的,我怎样才能以比第二个代码块中演示的更清晰的方式编写此代码?

标签: cfunctiontypes

解决方案


这是一个可以解决问题的解决方案。请注意,它void (*)(void)用作通用函数指针类型,而不是void *不能保证对函数指针起作用:

#include <stdio.h>

void (*f(void))(void);
void (*g(void))(void);

void (*f(void))(void)
{
    printf("This is f.\n");
    return (void (*)(void)) g;
}

void (*g(void))(void)
{
    printf("This is g.\n");
    return (void (*)(void)) f;
}

#define SRCALL(p)   ((void (*(*)(void))(void)) p())

int main(void)
{
    void (*(*p)(void))(void);

    p = f;

    p = SRCALL(p);
    p = SRCALL(p);
    p = SRCALL(p);

    return 0;
}

函数指针转换很难看,所以我将它们封装在宏中SRCALL(self-ref-call)。输出是:

This is f.
This is g.
This is f.

推荐阅读