这是否适用于void指针?

时间:2011-04-13 21:19:30

标签: c function-pointers void-pointers

这个问题是关于在特定实现中使用void指针的适当性。

我有一个相对简单的程序,它包含一个无限循环。在每个循环中,程序迭代固定范围的常量值并在每个值上调用一个函数。调用的特定函数可以是三个中的一个,并且在运行时由参数指定。在无限循环开始之前,有一个条件块,它根据提供的参数设置一个函数指针。这样,条件逻辑只需要运行一次,而不是每次循环中的每次迭代。

我已经实现了它并且运行良好,但是我希望在每次调用函数之间保持状态。我的建议是将状态存储在结构中,并在每个值上调用函数时传递该结构。问题是每个函数都需要一个不同的结构来存储其状态的不同值集,并且所有三个函数的原型必须兼容(对于函数指针)。我打算通过在三个函数的原型中使用void指针来解决这个问题,从而保持兼容的原型,但允许我将不同的结构传递给每个函数。

问题是;我的建议是否适当使用了void指针,或者它是否引入了太多的运行时动态,因此我应该重新考虑我的方法?

注意:不可能在三个函数中的每个函数中使用静态变量,因为结构也需要在无限循环中可用,因为在迭代值范围之前和之后还要进行一些处理。

5 个答案:

答案 0 :(得分:5)

只要你小心保持你的电话类型正确,这是完成你所描述的相当C语言的方法。

答案 1 :(得分:2)

您可以使用union

获得一些类型安全措施
typedef struct {
        int a;
        char *b;
} s1;
typedef struct {
        double d;
        int *e;
} s2;
typedef union {
        s1 s1;
        s2 s2;
} ocd;
typedef int (*daemon_function)(ocd *);

然后,您的所有功能都可以是daemon_function类型,但可以通过ocd.s1ocd2.s2采用不同的参数。我倾向于称之为一堆毫无意义的繁忙工作。一个简单的void*也可以正常工作。

您还可以在结构的前面加上一个幻数,然后功能可以通过查看幻数来检查类型安全性,看看它是否正确:

#define MAGIC 0x4d475600L
typedef struct {
    long magic;
    /* ... */
} whatever;

然后:

int f(void *p) {
    whatever *w = (whatever *)p;
    if(w->magic != MAGIC) {
        /* complain and go boom! */
    }
    /* ... */
}

我在Motif编程时代一直做着神奇的数字技巧,你在Motif / Xt / X11开发中传递了很多void*指针。

答案 2 :(得分:1)

void *在C语言中非常惯用。我个人经常使用它,但每当我这样做时,我倾向于使用标记结构来保证安全,即我在每个结构的开头放置一个唯一的类型ID来识别它

答案 3 :(得分:1)

Void指针是一种告诉c类型系统你想让它停止工作并相信你不要搞砸的方法。它是void *的适当用法,唯一的问题是您无法访问编译器执行的任何类型检查。您可以创建一些非常奇怪且难以诊断的错误。如果你确定你知道自己在做什么(听起来像你那样),并且如果你已经多次检查过代码的每一行,并且确定它没有逻辑错误,那么你应该没问题。 / p>

答案 4 :(得分:0)

一般来说没关系。 我真的更喜欢使用void *上下文,但看起来你想要避免使用它。 由于您已经有一些解析参数并选择函数的代码,您只需在开关中选择函数并为每次迭代显式调用它。