Я подозреваю, что вы действительно хотите не перечисления, а способ отображения целого числа в строку и обратно.Например, вы можете представлять месяцы и использовать целые числа для упрощения сравнения («эта дата раньше этой даты»), а строку - для более удобного для человека представления.
(мне пришлось угадать это, поскольку ваш вопрос не объяснил, что вы на самом деле пытаетесь решить.)
Если вы откажетесь от перечислений, вы можете написать небольшую вспомогательную библиотеку, которая решает эту проблему в общем виде.Действительно простым способом реализации сопоставления было бы использование простого массива строк и использование индекса в массиве в качестве целого числа:
#include <string.h>
/* Find string in mapping. Return -1 if not found. */
int map_string_to_int(char *map[], int count, char *string)
{
for (int i = 0; i < count; ++i) {
if (strcmp(map[i], string) == 0)
return i;
}
return -1;
}
/* Map int to string. Return NULL if not found. */
char *map_int_to_string(char *map[], int count, int i)
{
if (i < 0 || i >= count)
return NULL;
return map[i];
}
/* Add new string to mapping. Return its unique id. Return existing id if
string was in mapping already. Caller is responsible to make sure
there's room. Caller is responsible for making sure string does not
get de-allocated. */
int map_add(char *map[], int *count, char *string)
{
int i;
i = map_string_to_int(map, *count, string);
if (i == -1) {
i = *count;
map[i] = string;
++(*count);
}
return i;
}
/* A main program for testing, not actually part of the library. */
#include <stdio.h>
#define N 1024
int main(void)
{
char *map[N];
int count;
map_add(map, &count, "Monday");
map_add(map, &count, "Tuesday");
map_add(map, &count, "Thursday");
map_add(map, &count, "Wednesday");
map_add(map, &count, "Friday");
map_add(map, &count, "Sunday");
map_add(map, &count, "Saturday");
for (int i = 0; i < count; ++i)
printf("[%d] = %s\n", i, map_int_to_string(map, count, i));
printf("Monday is %d\n", map_string_to_int(map, count, "Monday"));
return 0;
}
Возможны более эффективные способы сделать это.Прежде чем начать работать с ними, не забудьте измерить, какое влияние это отображение на самом деле оказывает на вашу среду выполнения.
- Имейте второй массив, в котором хранятся отсортированные строки, и ищите строки с помощью бинарного поиска.Первая таблица остается, поэтому по-прежнему можно быстро отобразить целое число в строку.
- Использовать хеш-таблицу для второго массива.
- Полностью отказаться от первого массива и использовать значения хеш-функциикак целые числа, если вы можете найти хеш-функцию, которая не имеет коллизий для ваших конкретных данных.Это должно быть вполне осуществимо, если вы все равно собираетесь использовать перечисления, так как тогда набор значений будет фиксирован во время компиляции.(Хеш-таблица все еще нужна для обратного сопоставления: от целого числа к строке.)
Например, если ваши значения представляют дни недели, использование первых двух символов в качестве хеш-функции вполне достаточно.См. http://en.wikipedia.org/wiki/Perfect_hashing для указаний на некоторую связанную информацию о построении таких хеш-функций в общем случае.