用C通用数据类型[无效*] [英] Generic data type in C [ void * ]

查看:110
本文介绍了用C通用数据类型[无效*]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好我试图用void *为C.一个通用的数据类型,我要的是用我可以存储任何东西,得到什么的机制。我写了一些code,但它是在最后一种情况下失败。任何人都可以请看看在code,如果您有任何其他想法,请让我知道。

我知道我尝试存储,所以在这一点上我所知道的数据类型,但在再审我只知道的起始地址和大小。

下面是code:

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&ASSERT.H GT;
静态无效店面(void *的目的地,无效*源,为size_t大小){
    的memcpy((字符*)目的地,来源,大小);
}
静态无效检索(void *的目的地,无效*源,为size_t大小){
    的memcpy(目的地(字符*)来源,大小);
}无效* storage_char_ptr =(无效*)malloc的(sizeof的(字符*));
无效* storage_int_ptr =(无效*)malloc的(sizeof的为(int *));
无效* storage_int =(无效*)malloc的(的sizeof(INT));诠释主(){    INT int_in = 65;
    无效* int_out_ptr;
    为int * PTR =(INT *)malloc的(的sizeof(INT));
    的memcpy(PTR,和放大器; int_in,sizeof的(INT));    存储(storage_int_ptr,&安培; PTR,sizeof的为(int *));
    检索(安培; int_out_ptr,storage_int_ptr,sizeof的为(int *));
    断言(int_in == *(INT *)int_out_ptr);    字符* char_in =的HelloWorld!
    无效* char_out;
    存储(storage_char_ptr,&安培; char_in,sizeof的(字符*));
    检索(安培; char_out,storage_char_ptr,sizeof的(字符*));
    断言(STRCMP(char_in,(字符*)char_out)== 0);    char_in = _strdup(的HelloWorld!);
    存储(storage_char_ptr,&安培; char_in,sizeof的(字符*));
    检索(安培; char_out,storage_char_ptr,sizeof的(字符*));
    断言(STRCMP(char_in,(字符*)char_out)== 0);    / *这是它失败* /
    int_in = 55;
    无效* int_out;
    存储(storage_int,&安培; int_in,sizeof的(INT));
    检索(安培; int_out,storage_int,sizeof的(INT));
    断言(55 * ==(INT *)int_out);}


解决方案

这是更好的使用所有类型的工会,你需要,而不是无效* ,结合所选类型的枚举。
如果你没有一个类型有限列表,然后使用含有无效* 指针和至少分配大小的结构。

例如:

 结构ANYTYPE
{
    枚举{
      typUndefined,
      typInt,// 1
      typUint,
      typString,
      typByteString,
      typLong,// 5
      typFloat,
      typDouble,
    } ITYPE;    void *的价值;
};

这可以让你轻松正确释放内存,使通用code,可以作用于前值分析类型。
你必须与工会的类似选项:

 结构ANYTYPE
{
    枚举{
      typUndefined,
      typInt,// 1
      typUint,
      typString,
      typLong
    } ITYPE;    联盟
    {
        INT I;
        unsigned int类型U;
        字符* S;
        长升;
    }值;
}

在一个工会,所有的元素都使用相同的内存空间,只有一个应访问。通过枚举,你知道哪些元素应该进行访问。当然,你不必OO保护像在C ++中,所以你需要确保你正确设置枚举无处不在,你使用这个结构。

Hello I am trying to use void * as a generic data type in C. What I want is a mechanism using which I can store anything and get anything. I wrote some code, but it is failing in the last case. Can anybody please take a look at the code, If you have any other idea please let me know.

I know what I am trying to store, so at that point I know the data type, but during retrial I only know the starting address and size .

Here is the code :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>


static void store( void *destination, void *source, size_t size ) {
    memcpy ( (char*)destination, source, size);
}
static void retrieve ( void *destination, void *source, size_t size) {
    memcpy ( destination, (char*)source, size);
}

void *storage_char_ptr = (void*) malloc ( sizeof( char* ));
void *storage_int_ptr  = (void*) malloc ( sizeof(int*));
void *storage_int      = (void*) malloc ( sizeof( int));

int main() {

    int int_in = 65;
    void *int_out_ptr;
    int *ptr = ( int*) malloc ( sizeof(int));
    memcpy ( ptr, &int_in, sizeof(int));

    store ( storage_int_ptr, &ptr, sizeof(int*));
    retrieve ( &int_out_ptr, storage_int_ptr, sizeof(int*));
    assert ( int_in == *(int*)int_out_ptr);

    char *char_in = "HelloWorld!!";
    void *char_out;
    store ( storage_char_ptr, &char_in, sizeof(char*));
    retrieve ( &char_out, storage_char_ptr, sizeof(char*));
    assert ( strcmp ( char_in, (char*)char_out ) == 0 );

    char_in = _strdup("HelloWorld!!");
    store ( storage_char_ptr, &char_in, sizeof(char*));
    retrieve ( &char_out, storage_char_ptr, sizeof(char*));
    assert ( strcmp ( char_in, (char*)char_out ) == 0 );

    /* This is where it is failing */
    int_in = 55;
    void* int_out;
    store   ( storage_int, &int_in, sizeof(int));
    retrieve ( &int_out, storage_int, sizeof(int));
    assert  ( 55 == *(int*)int_out);

} 

解决方案

It's much better to use a union of all types you will need instead of void*, combined with an enumeration of the selected type. If you don't have a finite list of types, then use a struct containing void* pointer and the size allocated at least.

For example:

struct ANYTYPE
{
    enum {
      typUndefined,
      typInt,           // 1
      typUint,
      typString,
      typByteString,
      typLong,          // 5
      typFloat,
      typDouble,
    } iType;

    void* value;
};

This allows you to easily deallocate the memory correctly and make generic code that can analyze the type before acting on the value. You have a similar option with union:

struct ANYTYPE
{
    enum {
      typUndefined,
      typInt,           // 1
      typUint,
      typString,
      typLong
    } iType;

    union
    {
        int i;
        unsigned int u;
        char* s;
        long l;
    } value;
}

In a union, all elements are using same memory space and only one should be accessed. Via the enumeration, you know which element should be accessed. Of course you don't have OO protection like in C++, so you need to be sure you correctly set the enumeration everywhere you use this struct.

这篇关于用C通用数据类型[无效*]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆