C 语言实现 C# 中的泛型 Dictionary

news/2025/1/18 6:14:52/

好的,下面是一个简单的用 C 语言实现 C# 中的泛型 Dictionary 的示例代码,代码中有详细的注释,帮助你理解代码的实现细节。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 定义一个泛型键值对的结构体
typedef struct KeyValuePair {void *key;   // 用 void * 存储键void *value; // 用 void * 存储值
} KeyValuePair;// 定义一个泛型字典的结构体
typedef struct Dictionary {KeyValuePair *items; // 用键值对结构体存储字典的元素size_t size; // 存储键的大小size_t count; // 存储元素的数量size_t capacity; // 存储字典的容量
} Dictionary;// 定义一个哈希函数,用于计算键的哈希值
unsigned int Dictionary_HashFunction(Dictionary *dictionary, void *key) {// 将键的字节数据转换为 unsigned int 类型unsigned int hash = 0;unsigned char *p = (unsigned char *)key;for (size_t i = 0; i < dictionary->size; i++) {hash = 31 * hash + *p;p++;}return hash;
}// 初始化一个泛型字典
Dictionary *Dictionary_Init(size_t size) {Dictionary *dictionary = malloc(sizeof(Dictionary)); // 为字典结构体分配内存dictionary->items = malloc(sizeof(KeyValuePair) * 4); // 为字典元素分配内存dictionary->size = size; // 存储键的大小dictionary->count = 0; // 初始化元素数量为 0dictionary->capacity = 4; // 初始化字典容量为 4return dictionary; // 返回字典结构体的指针
}// 向泛型字典中添加一个键值对
void Dictionary_Add(Dictionary *dictionary, void *key, void *value) {// 如果字典的元素数量等于字典的容量,需要扩容if (dictionary->count == dictionary->capacity) {dictionary->capacity *= 2; // 容量扩大为原来的 2 倍dictionary->items = realloc(dictionary->items, sizeof(KeyValuePair) * dictionary->capacity); // 重新分配内存}// 计算键的哈希值unsigned int hash = Dictionary_HashFunction(dictionary, key);// 如果哈希值对应的元素已经存在,需要替换值for (size_t i = 0; i < dictionary->count; i++) {if (dictionary->items[i].key != NULL && memcmp(dictionary->items[i].key, key, dictionary->size) == 0) {dictionary->items[i].value = value; // 替换值return;}}// 如果哈希值对应的元素不存在,需要添加键值对dictionary->items[dictionary->count].key = malloc(dictionary->size); // 为键分配内存memcpy(dictionary->items[dictionary->count].key, key, dictionary->size); // 复制键的数据dictionary->items[dictionary->count].value = value; // 存储值dictionary->count++; // 元素数量加 1
}// 从泛型字典中获取一个值
void *Dictionary_Get(Dictionary *dictionary, void *key) {// 计算键的哈希值unsigned int hash = Dictionary_HashFunction(dictionary, key);// 查找哈希值对应的元素for (size_t i = 0; i < dictionary->count; i++) {if (dictionary->items[i].key != NULL && memcmp(dictionary->items[i].key, key, dictionary->size) == 0) {return dictionary->items[i].value; // 返回值}}// 如果哈希值对应的元素不存在,返回 NULLreturn NULL;
}// 从泛型字典中移除一个键值对
void Dictionary_Remove(Dictionary *dictionary, void *key) {// 计算键的哈希值unsigned int hash = Dictionary_HashFunction(dictionary, key);// 查找哈希值对应的元素for (size_t i = 0; i < dictionary->count; i++) {if (dictionary->items[i].key != NULL && memcmp(dictionary->items[i].key, key, dictionary->size) == 0) {// 释放键的内存free(dictionary->items[i].key);// 将字典中的元素向前移动for (size_t j = i; j < dictionary->count - 1; j++) {dictionary->items[j] = dictionary->items[j + 1];}dictionary->count--; // 元素数量减 1return;}}
}// 销毁一个泛型字典
void Dictionary_Destroy(Dictionary *dictionary) {// 释放字典中的键的内存for (size_t i = 0; i < dictionary->count; i++) {free(dictionary->items[i].key);}// 释放字典元素的内存free(dictionary->items);// 释放字典结构体的内存free(dictionary);
}int main() {// 初始化一个存储 int 类型的键和 char * 类型的值的泛型字典Dictionary *dictionary = Dictionary_Init(sizeof(int));// 向字典中添加键值对int a = 1, b = 2, c = 3;char *x = "hello", *y = "world", *z = "dictionary";Dictionary_Add(dictionary, &a, x);Dictionary_Add(dictionary, &b, y);Dictionary_Add(dictionary, &c, z);// 从字典中获取值char *p = Dictionary_Get(dictionary, &b);printf("%s\n", p); // 输出 world// 从字典中移除键值对Dictionary_Remove(dictionary, &b);// 销毁字典Dictionary_Destroy(dictionary);return 0;
}

希望这个示例代码能帮助你理解如何用 C 语言实现一个泛型字典。


http://www.ppmy.cn/news/404615.html

相关文章

Vision Pro:为什么空间音频是AR的绝杀武器?

Apple Vision Pro&#xff0c;不仅仅是苹果全新的重磅品类&#xff0c;而且在它身上也融合了苹果过去几乎所有新技术&#xff0c;比如空间音频就是其中一个例子。 苹果表示&#xff0c;Vision Pro中空间音频可以很好的应用在&#xff1a;影视节目、游戏内容、3D空间照片、3D空…

测试开发之Python自动化 Pytest 之 fixture

Pytest 之 fixture unittest 和 nose 都支持 fixture 的,但是 fixture 在 pytest 里使用更灵活。也算是 pytest 的一个闪光点吧可以理解为一个跟 setup 和 teardown 这种前后置类似的东西。但是比它们要强大、灵活很多 fixtur 当做参数传入 # -*- coding: utf-8 -*-import p…

Django高级扩展之文件上传

文件上传是一个比较常用的网站功能&#xff0c;在服务器端&#xff0c;Django会使用一个叫作request.FILES的对象来处理上传的文件。 目录 存储路径 创建存储目录 配置settings.py 上传单文件 配置url 上传文件模板 视图方法 显示上传页面 上传文件处理 上传效果 1.…

全网最详细的postman接口测试教程,一篇文章满足你

1、前言   之前还没实际做过接口测试的时候呢&#xff0c;对接口测试这个概念比较渺茫&#xff0c;只能靠百度&#xff0c;查看各种接口实例&#xff0c;然后在工作中也没用上&#xff0c;现在呢是各种各样的接口都丢过来&#xff0c;总算是有了个实际的认识。因为只是接口的…

谷歌android更新,谷歌Android系统:6年演变10次重大更新

转瞬之间&#xff0c;Android系统已经拥有超过6年的历史&#xff0c;从T-Mobile G1 开始到现在&#xff0c;谷歌前后已经发布了10次重要更新&#xff0c;每一次更新有新功能、有新Bug&#xff0c;也有后端的改进。相比之前&#xff0c;现在Android系统的更新速度明显放缓&#…

Android 4.0的冰淇淋三明治与苹果iOS 5

Android 4.0的冰淇淋三明治与苹果iOS 5   的Andr​​oid 4.0与iOS 5的   最近Android和苹果均发布了新的操作系统的移动设备;苹果的iOS 5和Android 4.0&#xff0c;也被称为冰淇淋三明治。香港专业教育学院采取观看视频和阅读他们的网站吹嘘的新进展和令人兴奋的升级&#…

谷歌创始人拉里·佩奇不为人知的故事

谷歌创始人拉里佩奇不为人知的故事 2014-4-27 17:52:13 出处&#xff1a;腾讯科技&#xff08;小贝&#xff09; 人气&#xff1a;31531次 评论&#xff08;27&#xff09; IT之家&#xff08;www.ithome.com&#xff09;&#xff1a;谷歌创始人拉里佩奇不为人知的故事 2001…

苹果 iPhome 对 Silverlight 与 Flash 无兴趣,Google 则通吃

微软最新的声明表示&#xff0c;苹果 iPhone 对微软的 Silvelight 与 Adobe Flash 几乎毫无兴趣&#xff0c;而 Goolge 的 Android 出于其开放的天性&#xff0c;则双双通吃。 微软副总裁 Scott Guthrie 承认&#xff0c;他们目前正同 Apple 商谈。微软非常希望 iPhone 可以运…