简体   繁体   English

如何制作泛型函数 C

[英]How to make a generic function C

I have to create an HashMap.我必须创建一个 HashMap。 I created two structs.我创建了两个结构。 A node struct and a table struct .一个node struct和一个table struct Second struct will "contain" my nodes.第二个结构将“包含”我的节点。 My trouble is the insert function: I have to insert in my table (*t) couple (key,value).我的麻烦是insert函数:我必须在我的表中插入 (*t) 对 (key,value)。 The problem is that key and value type must be generic.问题是键和值类型必须是通用的。 So , I would like to insert int, double, char, ecc.. How can I make my function into a generic function ?所以,我想插入 int、double、char、ecc.. 如何将我的函数变成通用函数

insert.c插入文件

struct node{
    int key;
    int val;
    struct node *next;
    struct node *prev;
};
struct table{
    int size;
    struct node **list;
};

int hashCode(int key){
    if(key>0)
        return key-1;
    return key+1;
}

void insert(struct table *t,int key,int val){
    int pos = hashCode(key);
    struct node *list = t->list[pos];
    struct node *newNode = (struct node*)malloc(sizeof(struct node));
    struct node *temp = list;
    while(temp){
        if(temp->key==key){
            printf("%s", "Key already created");
            return;
        }
        temp = temp->next;
    }
    newNode->next = list;
    newNode->key = key;
    newNode->val = val;
    if(list!=NULL){
        list->prev = newNode; 
    }
    t->list[pos] = newNode;
    newNode->prev = NULL;
}

main.c主文件

int main(){
    struct table *t = /* I create the structure */ ;
    insert(t,2,3);
    insert(t,3,4);
    insert(t,2,3);
    // insert(t,'a','c');  function insert should execute also with char, int, float, double ecc...
    return 0;
}

You define the union like this :你这样定义联合:

union value {
    int i;
    float f;
    char c;
//and so on
};

And your node like this :你的节点是这样的:

struct node{
    int key;
    union value val;
    struct node *next;
    struct node *prev;
};

You change your function argument like this :您可以像这样更改函数参数:

void insert(struct table *t, int key, union value val) {}

And your main becomes (I use a macro to simplify the creation of unions) :而你的主要变成(我使用宏来简化联合的创建):

#define UVAL(v, k) (union value){ .k = v}

int main(){
    struct table * t = NULL; //Todo

    insert(t, 2, UVAL(3, i) );
    insert(t, 3, UVAL(4, i));
    insert(t, 2, UVAL(3, i));
    return 0;
}

With some floats instead :用一些浮点数代替:

int main(){
    struct table * t = NULL; //Todo

    insert(t, 2, UVAL(3.5f, f));
    insert(t, 3, UVAL(4.f,  f));
    insert(t, 2, UVAL(3.5f, f));
    return 0;
}

Since C11 you can use _Generic从 C11 开始,您可以使用_Generic

#include <stdio.h>

#define hashCode(x) _Generic((x), \
    int: hash_int, \
    double: hash_double \
)(x)

int hash_int(int value)
{
    printf("Hashing %d\n", value);
    return 42;
}

int hash_double(double value)
{
    printf("Hashing %f\n", value);
    return 42;
}

int main(void)
{
    hashCode(3);
    hashCode(3.14);
    return (0);
}

From cppreference来自cppreference

Explanation解释

Provides a way to choose one of several expressions at compile time, based on a type of a controlling expression提供一种在编译时根据控制表达式的类型选择多个表达式之一的方法

First, the type of controlling-expression undergoes lvalue conversions.首先,控制表达式的类型经过左值转换。 The conversion is performed in type domain only: it discards the top-level cvr-qualifiers and atomicity and applies array-to-pointer/function-to-pointer transformations to the type of the controlling expression, without initiating any side-effects or calculating any values.转换仅在类型域中执行:它丢弃顶级 cvr 限定符和原子性并将数组到指针/函数到指针的转换应用于控制表达式的类型,而不会启动任何副作用或计算任何值。

The type after conversion is compared with type-names from the list of associations.转换后的类型与关联列表中的类型名称进行比较。

If the type is compatible with the type-name of one of the associations, then the type, value, and value category of the generic selection are the type, value, and value category of the expression that appears after the colon for that type-name.如果类型与关联之一的类型名称兼容,则泛型选择的类型、值和值类别是该类型冒号后出现的表达式的类型、值和值类别 -姓名。

If none of the type-names are compatible with the type of the controlling-expression, and the default association is provided, then the type, value, and value category of the generic selection are the type, value, and value category of the expression after the default : label.如果没有一个类型名与控制表达式的类型兼容,并且提供了默认关联,那么泛型选择的类型、值和值类别就是表达式的类型、值和值类别在默认值之后:标签。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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