Tips på hur man skapar en Map i C
Jag vill göra en Map i C. Om ni inte vet vad en Map är så är det en dynamisk lista som innehåller objekt där objekten kan variera. I detta fall så får listan INTE vara dynamisk, den ska vara fixerad för jag vet ändå alla element. Men skapandet av mappen får ske dynamiskt. Men användandet måste vara statiskt.
Låt oss säga att vi har en Map i C och vi har ett två parametervärden, index och sub_index. Index är uint16_t och sub_index är uint8_t. Vi säger nu att mappen ser ut så här Map<index, sub_index> i pesudokod.
Problemet är att varje map ska länka till en heltal i from av uint8_t, uint16_t eller uint32_t.
Så om jag tar fram min mapp och säger Map<0x1000, 0x1> så ska jag kunna komma åt t.ex. ett uin32_t värde och sätta det värdet. Eller om jag säger Map<0x1000, 0x0> så kommer jag åt ett uint8_t värde som jag kan sätta eller läsa.
Hur kan jag göra detta i C?
Vad tror ni om denna kod som presenterar tre funktioner? Kan ni göra bättre?
Testa koden här: https://onlinegdb.com/DUij_UV4m
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
/* Vår map */
struct Map{
uint16_t index;
uint8_t sub_index;
void* value;
struct Map *next_map;
};
/* Addera ett nytt värde */
bool add_new_value(struct Map* start, uint16_t index, uint8_t sub_index, void* value){
/* Plocka fram sista mappen som har next_map == NULL */
struct Map* map = start;
while(map->next_map != NULL){
/* Men kolla om index och sub_index inte är upptagna */
if(map->index == index && map->sub_index == sub_index)
return false;
/* OK - Välj nästa mapp */
map = map->next_map;
}
/* Här är sista mappen */
map->index = index;
map->sub_index = sub_index;
map->value = value;
/* Skapa ny map */
map->next_map = malloc(sizeof(struct Map));
}
/* Plocka fram ett värde */
bool bring_value(struct Map* start, uint16_t index, uint8_t sub_index, void* value){
/* Iterera tills vi hittar next_map som är NULL */
struct Map* map = start;
while(map->next_map != NULL){
/* Ta fram värdet */
if(map->index == index && map->sub_index == sub_index){
value = map->value;
return true; /* Värde hittat */
}
/* Hittade inte mappen - Välj nästa mapp */
map = map->next_map;
}
return false; /* Värde hittades inte */
}
/* Plocka fram ett värde */
bool change_value(struct Map* start, uint16_t index, uint8_t sub_index, void* value){
/* Iterera tills vi hittar next_map som är NULL */
struct Map* map = start;
while(map->next_map != NULL){
/* Ta fram värdet */
if(map->index == index && map->sub_index == sub_index){
map->value = value;
return true; /* Värde applicerat */
}
/* Hittade inte mappen - Välj nästa mapp */
map = map->next_map;
}
return false; /* Värdet kunde inte appliceras */
}
int main(){
/* Skapa våran mapp */
struct Map map;
/* Addera ett värde */
uint8_t temperatur = 20;
bool add_temperatur = add_new_value(&map, 0x1000, 0x0, &temperatur);
printf("Added temperatur status: %s . Value = %i\n", add_temperatur ? "true" : "false", temperatur);
/* Addera annat värde på samma index */
uint8_t temperatur2 = 40;
bool add_temperatur2 = add_new_value(&map, 0x1000, 0x0, &temperatur);
printf("Added temperatur status: %s . Value = %i\n", add_temperatur2 ? "true" : "false", temperatur2);
/* Ta fram ett värde för variabeln temperatur */
bool bring_temperatur = bring_value(&map, 0x1000, 0x0, &temperatur);
printf("Bring temperatur status: %s . Value = %i\n", bring_temperatur ? "true" : "false", temperatur);
/* Ta fram ett värde för variabeln temperatur på ett felaktigt index som aldrig har använts */
bring_temperatur = bring_value(&map, 0x1000, 0x1, &temperatur);
printf("Bring temperatur status: %s . Value = %i\n", bring_temperatur ? "true" : "false", temperatur);
/* Ändra nu temperatur till något annat */
temperatur = 100;
bool change_temperatur = change_value(&map, 0x1000, 0x0, &temperatur);
printf("Change temperatur status: %s . Value = %i\n", change_temperatur ? "true" : "false", temperatur);
/* Ändra nu temperatur till något annat på ett index som inte finns */
temperatur = 200;
change_temperatur = change_value(&map, 0x2000, 0x0, &temperatur);
printf("Change temperatur status: %s . Value = %i\n", change_temperatur ? "true" : "false", temperatur);
/* Addera nu ett nytt värde, med annan datatyp */
uint16_t lenght = 13443;
bool add_length = add_new_value(&map, 0x1000, 0x1, &lenght);
printf("Add length status: %s . Value = %i\n", add_length ? "true" : "false", lenght);
/* Ändra lenght */
lenght = 15000;
bool change_length = change_value(&map, 0x1000, 0x1, &lenght);
printf("Change length status: %s . Value = %i\n", change_length ? "true" : "false", lenght);
/* Plocka fram length */
bool bring_length = bring_value(&map, 0x1000, 0x1, &lenght);
printf("Bring length status: %s . Value = %i\n", bring_length ? "true" : "false", lenght);
return 0;
}