欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > [学习] 在C语言中使用字典(附示例)

[学习] 在C语言中使用字典(附示例)

2025/6/21 12:06:01 来源:https://blog.csdn.net/jz_ddk/article/details/148796535  浏览:    关键词:[学习] 在C语言中使用字典(附示例)

在C语言中使用字典(附示例)

文章目录

  • 在C语言中使用字典(附示例)
    • 一、引言
    • 二、字典的基本概念
      • 1. 数据结构定义
      • 2. 实现方式
    • 三、C语言中字典的实现
      • 1. 定义基本结构
      • 2. 哈希函数(字符串哈希)
      • 3. 插入键值对
      • 4. 查找键值
      • 5. 销毁字典释放内存
    • 四、字典的应用场景及示例代码
      • 场景一:配置管理器(读取配置键值对)
        • ✅ 应用描述:
        • ✅ 示例代码:
        • ✅ 配置文件 `config.txt` 内容:
      • 场景二:单词计数器(统计词频)
        • ✅ 应用描述:
        • ✅ 示例代码:
    • 五、使用哈希表实现字典
      • 1. 核心设计思路
      • 2. 核心代码
      • 3. 测试验证程序
    • 六、结语


一、引言

在现代编程中,字典(Dictionary) 是一种非常重要的数据结构,它以 键值对(Key-Value Pair) 的形式存储数据,并通过键快速查找对应的值。虽然 C 语言本身没有内置的字典类型(如 Python 中的 dict 或 Java 中的 HashMap),但我们可以使用 结构体 + 哈希表 的方式手动实现一个高效的字典。

本文将详细介绍:

  • 字典的基本概念和原理;
  • C语言中如何自定义实现字典;
  • 字典的常见应用场景;
  • 提供完整的可编译运行的 C 示例代码。

二、字典的基本概念

1. 数据结构定义

字典是一种关联数组(Associative Array),由一组键值对组成,其中:

  • 键(Key) 是唯一的,用于标识对应的数据项。
  • 值(Value) 是与键相关联的数据。

例如:

KeyValue
“name”“Alice”
“age”25
“email”“alice@abc.com”

2. 实现方式

C语言中可以通过以下结构实现字典:

  • 使用 哈希表(Hash Table) 来提升查找效率。
  • 每个哈希桶(Bucket)是一个链表节点,解决冲突问题(拉链法)。

三、C语言中字典的实现

1. 定义基本结构

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define TABLE_SIZE 100typedef struct Entry {char* key;char* value;struct Entry* next;
} Entry;typedef struct Dictionary {Entry* table[TABLE_SIZE];
} Dictionary;

2. 哈希函数(字符串哈希)

unsigned int hash(const char* key) {unsigned long int value = 0;while (*key)value = value * 37 + *key++;return value % TABLE_SIZE;
}

3. 插入键值对

void dict_set(Dictionary* dict, const char* key, const char* value) {unsigned int index = hash(key);Entry* entry = dict->table[index];// 如果已存在该键,更新值while (entry != NULL) {if (strcmp(entry->key, key) == 0) {free(entry->value);entry->value = strdup(value);return;}entry = entry->next;}// 否则创建新条目Entry* newEntry = (Entry*)malloc(sizeof(Entry));newEntry->key = strdup(key);newEntry->value = strdup(value);newEntry->next = dict->table[index];dict->table[index] = newEntry;
}

4. 查找键值

char* dict_get(Dictionary* dict, const char* key) {unsigned int index = hash(key);Entry* entry = dict->table[index];while (entry != NULL) {if (strcmp(entry->key, key) == 0)return entry->value;entry = entry->next;}return NULL; // 未找到
}

5. 销毁字典释放内存

void dict_destroy(Dictionary* dict) {for (int i = 0; i < TABLE_SIZE; i++) {Entry* entry = dict->table[i];while (entry != NULL) {Entry* tmp = entry;entry = entry->next;free(tmp->key);free(tmp->value);free(tmp);}}
}

四、字典的应用场景及示例代码

场景一:配置管理器(读取配置键值对)

✅ 应用描述:

从文本文件中读取配置项并存入字典,便于后续程序调用。

✅ 示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 此处插入上述字典定义和函数int main() {FILE* fp = fopen("config.txt", "r");if (!fp) {printf("无法打开配置文件\n");return 1;}Dictionary config;memset(&config, 0, sizeof(config));char line[256];while (fgets(line, sizeof(line), fp)) {char* key = strtok(line, "=");char* value = strtok(NULL, "\n");if (key && value) {dict_set(&config, key, value);}}fclose(fp);printf("host: %s\n", dict_get(&config, "host"));printf("port: %s\n", dict_get(&config, "port"));dict_destroy(&config);return 0;
}
✅ 配置文件 config.txt 内容:
host=localhost
port=8080
username=admin
password=secret

📌 编译命令:

gcc -o config_reader config_reader.c

场景二:单词计数器(统计词频)

✅ 应用描述:

读取一段英文文本,统计每个单词出现的次数。

✅ 示例代码:
#include <ctype.h>int main() {Dictionary word_count;memset(&word_count, 0, sizeof(word_count));char text[] = "hello world hello c programming is fun and hello world";char* token = strtok(text, " ");while (token != NULL) {char* count_str = dict_get(&word_count, token);int count = count_str ? atoi(count_str) : 0;char buffer[10];sprintf(buffer, "%d", count + 1);dict_set(&word_count, token, buffer);token = strtok(NULL, " ");}for (int i = 0; i < TABLE_SIZE; i++) {Entry* entry = word_count.table[i];while (entry != NULL) {printf("%s: %s\n", entry->key, entry->value);entry = entry->next;}}dict_destroy(&word_count);return 0;
}

📌 编译命令:

gcc -o word_counter word_counter.c

五、使用哈希表实现字典

1. 核心设计思路

我们将构建以下组件:

组件描述
Entry存储键值对的节点结构
HashTable哈希表结构,包含多个桶(bucket)
hash()哈希函数,计算字符串键对应的索引
ht_put()插入或更新键值对
ht_get()获取指定键的值
ht_remove()删除指定键
ht_destroy()销毁哈希表并释放内存

2. 核心代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 定义哈希表大小
#define TABLE_SIZE 128// 单个键值对结构体
typedef struct Entry {char* key;char* value;struct Entry* next; // 冲突解决:拉链法
} Entry;// 哈希表结构体
typedef struct HashTable {Entry* table[TABLE_SIZE];
} HashTable;// 哈希函数:简单字符串哈希算法
unsigned int hash(const char* key) {unsigned long int value = 0;while (*key)value = value * 37 + *key++;return value % TABLE_SIZE;
}// 创建新条目
Entry* create_entry(const char* key, const char* value) {Entry* entry = (Entry*)malloc(sizeof(Entry));entry->key = strdup(key);entry->value = strdup(value);entry->next = NULL;return entry;
}// 初始化哈希表
HashTable* ht_create() {HashTable* table = (HashTable*)malloc(sizeof(HashTable));for (int i = 0; i < TABLE_SIZE; ++i)table->table[i] = NULL;return table;
}// 插入或更新键值对
void ht_put(HashTable* table, const char* key, const char* value) {unsigned int index = hash(key);Entry* current = table->table[index];// 如果键已存在,更新值while (current != NULL) {if (strcmp(current->key, key) == 0) {free(current->value);current->value = strdup(value);return;}current = current->next;}// 否则插入新条目Entry* new_entry = create_entry(key, value);new_entry->next = table->table[index];table->table[index] = new_entry;
}// 查找键对应的值
char* ht_get(HashTable* table, const char* key) {unsigned int index = hash(key);Entry* current = table->table[index];while (current != NULL) {if (strcmp(current->key, key) == 0)return current->value;current = current->next;}return NULL; // 未找到
}// 删除指定键
void ht_remove(HashTable* table, const char* key) {unsigned int index = hash(key);Entry* current = table->table[index];Entry* prev = NULL;while (current != NULL) {if (strcmp(current->key, key) == 0) {if (prev == NULL)table->table[index] = current->next;elseprev->next = current->next;free(current->key);free(current->value);free(current);return;}prev = current;current = current->next;}
}// 销毁整个哈希表
void ht_destroy(HashTable* table) {for (int i = 0; i < TABLE_SIZE; ++i) {Entry* current = table->table[i];while (current != NULL) {Entry* tmp = current;current = current->next;free(tmp->key);free(tmp->value);free(tmp);}}free(table);
}

3. 测试验证程序

下面是一个完整的测试程序,演示如何使用上述哈希表字典:

int main() {HashTable* table = ht_create();// 插入键值对ht_put(table, "name", "Alice");ht_put(table, "age", "30");ht_put(table, "email", "alice@example.com");// 修改已有键ht_put(table, "age", "31");// 查找键printf("name: %s\n", ht_get(table, "name"));printf("age: %s\n", ht_get(table, "age"));printf("email: %s\n", ht_get(table, "email"));// 删除键ht_remove(table, "email");// 尝试获取被删除的键printf("email after remove: %s\n", ht_get(table, "email")); // 应为 NULL// 释放资源ht_destroy(table);return 0;
}

📌 编译命令(GCC / MinGW):

gcc -o hash_table_dict hash_table_dict.c

📌 运行结果:

name: Alice
age: 31
email: alice@example.com
email after remove: (null)

六、结语

虽然 C 语言没有内置字典结构,但通过结构体和哈希表可以高效地实现这一功能。掌握字典的底层实现原理,有助于我们编写更高效、灵活的程序。希望本篇博客能帮助你理解并掌握 C 语言中字典的设计与应用!


研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)


版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词