简体   繁体   中英

Conversions of different data types

I am new to C and trying to create an analogue of the dictionary, and ran into a typing problem. My dictionary knows how to create a key-value only for const char , I wanted to expand the program so that it could also use values of other data types, tried to use a pointer to void, but the problem remained and I had a few questions:

Is it possible to make so that the function has converted the dictionary different types of data?

How can I do this?

main code:

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

#define MAXSIZE 5000

struct base
{
    uint8_t *up;
    uint8_t size;
};

typedef struct
{
    struct base key[MAXSIZE];
    struct base data[MAXSIZE];
    uint8_t index;
} dict_t;

static dict_t *init (uint8_t s_key, uint8_t s_data)
{
    dict_t *dict;

    dict = (dict_t *) malloc(sizeof(dict_t));
    dict -> key -> up = (uint8_t *) malloc(s_key);
    dict -> data -> up = (uint8_t *) malloc(s_data);

    dict -> key -> size = s_key;
    dict -> data -> size = s_data;
    dict -> index = 1;

    return dict;
}

dict_t *newDict (const char *key, const char *data)
{
    dict_t *dict;
    uint8_t s_key;
    uint8_t s_data;

    s_key = strlen(key);
    s_data = strlen(data);

    dict = init(s_key, s_data);

    memcpy(dict -> key, key, s_key);
    memcpy(dict -> data, data, s_data);

    return dict;
}

void printDict (dict_t *dict)
{
    for (int i = 0; i < dict -> index; i++)
    {
        fwrite(dict -> key, sizeof(uint8_t), dict -> key -> size, stdout);
        fwrite(": ", sizeof(char), 2, stdout);
        fwrite(dict -> data, sizeof(uint8_t), dict -> data -> size, stdout);
    }
}

main function

#include "dict.c"

int main ()
{
    dict_t *dict;

    dict = newDict("key", "data\n");
    printDict(dict);

    return 0;
}

Thanks a lot.

Short answer: You can't (but look at long answer).

Long answer:

There are two tricks you can use, although they are not perfect.

The first one is void pointers.

Void pointers have no type, so can be used to point to a value of any pointer. However, the pointer does not store the type of the value it points to. This can cause issues as you have to use a type cast to dereference it, which requires you to know the type before hand. You could use a struct to store the type as well as the pointer, then use if statements to dereference it appropriately:

enum Type {
    Int,
    Str
    //add more types
}
struct base {
    enum Type type;
    void *value;
}

The second trick is using unions. Very similar to the first one, just using a union instead of a void pointer:

enum Type {
    Int,
    Str
    //add more types here
}
struct base {
    enum Type type;
    union {
        int i;
        char s[20];
        //add more types here
    } values;
}

You would again use if statements to choose the correct field of the union.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM