在C中使用void *代替重载?

时间:2010-12-08 21:18:39

标签: c function void-pointers

我的问题是我在多线程应用程序中看到过这样的代码:

void Thread( void* pParams )
{  
    int *milliseconds = (int *)pParams;
    Sleep(milliseconds);
    printf("Finished after %d milliseconds", milliseconds); //or something like that
}

这引起了我的兴趣,我知道malloc发回一个void指针,你可以把它转换成你想要的,这是否意味着我可以创建一个可以接受任何数据类型的函数?

例如我在没有测试的情况下编写的函数:

void myfunc( void* param )
{  
    switch(sizeof(param)) {
       case 1:
       char *foo = (char *)param; break;
       case 2:
       short *foo = (short *)param; break;
       case 4: 
       int *foo = (int *)param; break;
    }
}
myfunc(3.1415);
myfunc(0);
myfunc('a');

我可能完全错了,即使这确实有效也是可怕的做法?感谢。

5 个答案:

答案 0 :(得分:7)

是的,void *非常适合创建通用函数。但是,一旦将指向某个数据类型的指针传递给采用void *的函数,就会丢失所有类型信息。一种控制程序的方法,以便它知道你传入的类型是第二个类型为enum的参数,它可能有INT,FLOAT,DOUBLE等值。

#include <stdio.h>

typedef enum inputTypes
{
    INT,
    DOUBLE,
    CHAR
} inType;

void myfunc(void*, inType);

int main(void)
{
    int    i = 42;
    double d = 3.14;
    char   c = 'a';

    myfunc(&i, INT);
    myfunc(&d, DOUBLE);
    myfunc(&c, CHAR);

    return 0;
}

void myfunc(void* param, inType type)
{  
    switch(type) {
       case INT:
           printf("you passed in int %d\n", *((int *)param));
           break;
       case DOUBLE:
           printf("you passed in double %lf\n", *((double *)param));
           break; 
       case CHAR: 
           printf("you passed in char %c\n", *((char *)param));
           break;
    }
}

输出

you passed in int 42
you passed in double 3.140000
you passed in char a

答案 1 :(得分:7)

是的,可以创建一个接受多种类型的函数,但这不是你做的。

myfunc中,sizeof(param)将始终相同:sizeof在编译时确定,并且将是指针的大小。

它适用于线程的原因,它通常由编码器知道指针在编译时指向的内容,并且您需要的只是一个简单的强制转换。如果您在编译时不知道void *指向的内容,则必须以某种方式在运行时传递它。

void *的密钥:您只能将它们放回原来的任何位置,由您自己知道它是什么。一个简单的void *本身无法告诉你它指向的是什么。

答案 2 :(得分:0)

sizeof(param)将始终返回指针的大小,因此如果您使用的是64位系统,则大概为8。这与它指向的内容无关。

答案 3 :(得分:0)

不起作用,因为sizeof(param)试图获取指针的大小。

答案 4 :(得分:0)

void*的大小完全取决于系统并在编译时确定,而不是在其中实际包含的内容。