你缺少的是一个集合。大多数语言都有一种数据类型,称为字典或映射或关联数组或其一些变体。 C 没有这种类型的数据结构;实际上,您在 C 中内置的唯一集合类型是数组。所以,如果你想要一些可以提供密钥并获得价值的东西,你必须自己动手或在互联网上找到一个。后者可能更可取,因为如果您自己动手(特别是如果您是初学者),您可能会犯错误并产生缓慢的数据结构。
为了让您了解最终的结果,这里有一个简单的示例:
你需要一些东西来代表这个系列;暂时称它为ListMap:
struct ListMap;
以上称为不完全类型。目前,我们并不关心其中的内容。除了将指针传递给周围的实例之外,您无法做任何事情。
您需要一个函数来将项目插入您的集合。它的原型看起来像这样:
bool listMapInsert(struct ListMap* collection, int key, const char* value);
// Returns true if insert is successful, false if the map is full in some way.
您需要一个函数来检索任何一个键的值。
const char* listMapValueForKey(struct ListMap* collection, int key);
你还需要一个函数来初始化集合:
struct ListMap* newListMap();
然后扔掉:
void freeListMap(struct ListMap* listMap);
难点在于实现这些功能如何完成它们的工作。无论如何,以下是您将如何使用它们:
struct ListMap* myMap = newListMap();
listMapInsert(myMap, 1, "foo");
listMapInsert(myMap, 1729, "taxi");
listMapInsert(myMap, 28, "perfect");
char* value = listMapValueForKey(myMap, 28); // perfect
freeListMap(myMap);
这是一个简单的实现。这只是为了说明,因为我没有对其进行测试,并且搜索条目会随着条目的数量线性增加(您可以比使用哈希表和其他结构做得更好)。
enum
{
listMapCapacity = 20
};
struct ListMap
{
struct key_value kvPairs[listMapCapacity];
size_t count;
};
struct ListMap* newListMap()
{
struct ListMap* ret = calloc(1, sizeof *ret);
ret->count = 0; // not strictly necessary because of calloc
return ret;
}
bool listMapInsert(struct ListMap* collection, int key, const char* value)
{
if (collection->count == listMapCapacity)
{
return false;
}
collection->kvPairs[count].key = key;
collection->kvPairs[count].value = strdup(value);
count++;
return true;
}
const char* listMapValueForKey(struct ListMap* collection, int key)
{
const char* ret = NULL;
for (size_t i = 0 ; i < collection->count && ret == NULL ; ++i)
{
if (collection->kvPairs[i].key == key)
{
ret = kvPairs[i].value;
}
}
return ret;
}
void freeListMap(struct ListMap* listMap)
{
if (listMap == NULL)
{
return;
}
for (size_t i = 0 ; i < listMap->count ; ++i)
{
free(listMap->kvPair[i].value);
}
free(listMap);
}