Как создать таблицу значений ключей значений из структуры в C? - PullRequest
0 голосов
/ 03 августа 2020

У меня есть структура значений:

struct Inst
{
    int opc;
    int opc2;
    int opc3;
    int imm;
    int imm2;
    int rs1;
    int rs2;
    int rd;
};

Для каждого значения я хочу, чтобы была соответствующая строка, представляющая это значение. Итак, если opc = 0x3, то соответствующая ему строка будет "OP-IMM". Итак, значение может быть вводом, о котором я знаю. Просто нужно сопоставить это значение с соответствующей строкой. Функционально это будет выглядеть так:

printf("%s", lookup(opc)) // If the value is 0x37, then it prints LUI, if it's 0x6F, then it prints JAL etc...

Как мне это сделать?

Ответы [ 2 ]

1 голос
/ 03 августа 2020

Если у вас мало чисел (некоторые из них относительны; на самом деле может быть легко миллион без проблем, в зависимости от системы), и нумерация, в которой все возможные числа в допустимом диапазоне имеют значение или, по крайней мере, большая часть их, у вас может быть простой массив.

У нас будет следующая таблица кодов:

0x0: invalid
0x1: "aaa"
0x2: "bbb"
0x3: "ccc"
0x4: invalid
0x5: "ddd"

Простой и эффективный способ создания таблицы поиска следующий:

const char lut[6][MAX_STRINGLEN + 1] = {
        NULL, "aaa", "bbb", "ccc", NULL, "ddd"
};

И используйте строку, просто вызывая массив по индексу кода lut[opcode].

В C2x (следующая версия стандарта) есть способ инициализировать массив с помощью двоичного файла, что, если размер массива очень большой, может означать значительное улучшение времени компиляции.

1 голос
/ 03 августа 2020

Следующий код делает то, что вы хотите ... Я предполагаю, что у вас не так много инструкций. Если у вас гораздо больше инструкций, таких как Million, вы должны использовать Balanced Binary Search Tree вместо array. (Примечание: я использую линейный поиск, чтобы найти соответствующий ключ со средней сложностью поиска O (n) для каждого поиска).

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct {
    int *keys; // this to hold keys
    char **vals; // this to hold valsues or strings
    int size;
    int capacity;
} Table;

Table *getTable(int capacity) {
    Table *table = (Table *)malloc(sizeof(Table));

    table->keys = malloc(sizeof(int) * capacity);
    table->vals = malloc(sizeof(char *) * capacity);
    
    table->size = 0;
    table->capacity = capacity;
    
    return table;
}

int insert(Table *table, int key, char *val) {
    if(table->size >= table->capacity) {
        // couldn't add more key/val pairs
        // capacity overflowed
        return 0;
    }
    // copy val into new dymanic char array string
    int l = strlen(val);
    char *buf = malloc(sizeof(char) * (l+1)); // l+1 for null char at the end
    strcpy(buf, val);

    table->keys[table->size] = key;
    table->vals[table->size] = val;

    table->size++;
    return 1; // key/val pair add is successful
}

char *lookup(Table *table, int key) {
    for(int i=0; i<table->size; i++) {
        if(table->keys[i] == key) {
            return table->vals[i];
        }
    }
    return NULL;
}

void destroyTable(Table *table) {
    for(int i=0; i<table->size; i++) {
        free(table->vals[i]);
    }
    free(table->keys);
    free(table->vals);
    free(table);
}

int main() {
    int capacity = 10;
    Table *table = getTable(capacity);

    int k1 = 12;
    char *v1 = "hello";

    int k2 = 19;
    char *v2 = "world!";

    insert(table, k1, v1);
    insert(table, k2, v2);

    char *val = lookup(table, k1);
    printf("%d: %s\n", k1, val);

    val = lookup(table, k2);
    printf("%d: %s\n", k2, val);

    destroyTable(table);

    return 0;
}

И вывод для моего ввода был:

12: hello
19: world!

, что гарантирует правильную работу.

Также обратите внимание, что я использовал десятичное целое число. Для использования шестнадцатеричного числа вы можете сделать следующее:

int key = 0x37;

И все готово ...

[PS]: не стесняйтесь спрашивать, если что-то неясно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...