Maps in C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// A simple key-value pair structure
typedef struct {
char* key;
int value;
} KeyValue;
// A simple map structure
typedef struct {
KeyValue* pairs;
int size;
int capacity;
} Map;
// Function to create a new map
Map* makeMap() {
Map* m = malloc(sizeof(Map));
m->pairs = NULL;
m->size = 0;
m->capacity = 0;
return m;
}
// Function to set a key-value pair in the map
void setKeyValue(Map* m, const char* key, int value) {
for (int i = 0; i < m->size; i++) {
if (strcmp(m->pairs[i].key, key) == 0) {
m->pairs[i].value = value;
return;
}
}
if (m->size == m->capacity) {
m->capacity = m->capacity == 0 ? 1 : m->capacity * 2;
m->pairs = realloc(m->pairs, m->capacity * sizeof(KeyValue));
}
m->pairs[m->size].key = strdup(key);
m->pairs[m->size].value = value;
m->size++;
}
// Function to get a value from the map
int getValue(Map* m, const char* key, int* found) {
for (int i = 0; i < m->size; i++) {
if (strcmp(m->pairs[i].key, key) == 0) {
*found = 1;
return m->pairs[i].value;
}
}
*found = 0;
return 0;
}
// Function to delete a key-value pair from the map
void deleteKeyValue(Map* m, const char* key) {
for (int i = 0; i < m->size; i++) {
if (strcmp(m->pairs[i].key, key) == 0) {
free(m->pairs[i].key);
for (int j = i; j < m->size - 1; j++) {
m->pairs[j] = m->pairs[j + 1];
}
m->size--;
return;
}
}
}
// Function to clear the map
void clearMap(Map* m) {
for (int i = 0; i < m->size; i++) {
free(m->pairs[i].key);
}
free(m->pairs);
m->pairs = NULL;
m->size = 0;
m->capacity = 0;
}
// Function to print the map
void printMap(Map* m) {
printf("map: {");
for (int i = 0; i < m->size; i++) {
printf("%s:%d", m->pairs[i].key, m->pairs[i].value);
if (i < m->size - 1) {
printf(" ");
}
}
printf("}\n");
}
int main() {
// Create an empty map
Map* m = makeMap();
// Set key/value pairs
setKeyValue(m, "k1", 7);
setKeyValue(m, "k2", 13);
// Print the map
printMap(m);
// Get a value for a key
int found;
int v1 = getValue(m, "k1", &found);
printf("v1: %d\n", v1);
// Get a value for a non-existent key
int v3 = getValue(m, "k3", &found);
printf("v3: %d\n", v3);
// Print the length of the map
printf("len: %d\n", m->size);
// Delete a key/value pair
deleteKeyValue(m, "k2");
printMap(m);
// Clear the map
clearMap(m);
printMap(m);
// Check if a key exists
int prs = getValue(m, "k2", &found);
printf("prs: %s\n", found ? "true" : "false");
// Create and initialize a new map in one line
Map* n = makeMap();
setKeyValue(n, "foo", 1);
setKeyValue(n, "bar", 2);
printMap(n);
// Clean up
clearMap(m);
free(m);
clearMap(n);
free(n);
return 0;
}
This C code demonstrates the implementation of a simple map (associative array) data structure. Here’s an explanation of the key points:
We define a
KeyValue
struct to represent key-value pairs and aMap
struct to hold the collection of pairs.The
makeMap
function creates an empty map.setKeyValue
adds or updates a key-value pair in the map.getValue
retrieves a value for a given key, with a boolean flag to indicate if the key was found.deleteKeyValue
removes a key-value pair from the map.clearMap
removes all key-value pairs from the map.printMap
is a utility function to display the contents of the map.In the
main
function, we demonstrate various operations on the map:- Creating an empty map
- Setting key-value pairs
- Retrieving values
- Checking the length of the map
- Deleting a key-value pair
- Clearing the map
- Checking for the existence of a key
Note that this implementation is a simplified version and doesn’t include some of the more advanced features of Go’s maps, such as built-in iteration or thread-safety. In a real-world C program, you might want to use a more sophisticated hash table implementation for better performance and additional features.
To compile and run this program:
$ gcc -o maps maps.c
$ ./maps
map: {k1:7 k2:13}
v1: 7
v3: 0
len: 2
map: {k1:7}
map: {}
prs: false
map: {foo:1 bar:2}
This output demonstrates the various operations performed on the map, similar to the Go example.