Можно ли добавить значения в перечисление C после его создания? - PullRequest
3 голосов
/ 16 марта 2012

Я попытался найти его в Google, но ничего не нашел.Кто-нибудь знает, можно ли это сделать?Если нет, то есть ли элегантная работа вокруг этого?

Обновление: я думаю, что ответ Фрэнка Остерфельда - самое ясное решение.Спасибо за все остальные ответы, я проголосовал за ваши ответы.

Ответы [ 6 ]

5 голосов
/ 16 марта 2012

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

Если вам просто нужны некоторые константы и вы хотите расширить их для особого случая, вы можетеиспользуйте несколько объявлений enum, одно расширяет другое, а затем использует int для хранения значений:

enum Error { NoError=0, AllIsBroken, WhatTheHellAreYouDoing, UserDefinedError };

enum NetworkError { HostNotFound=UserDefinedError+1, ConnectionTimeout, ... };

int error = HostNotFound;

if ( error == NoError )
    ...
if ( error == HostNotFound )
    ...
5 голосов
/ 16 марта 2012

Вы не можете открыть одно и то же перечисление с другим значением:

enum Colors { Red, Blue, Yellow };
enum Colors { Green = 3 }; // ERROR

Однако в C все перечисления автоматически конвертируются друг в друга.Так что просто создайте новое перечисление, как это:

enum Colors { Red, Blue, Yellow };
enum MoreColors { Green = 3 };

int foo()
{
  enum Colors c;
  c = Green; // This will compile
}
4 голосов
/ 16 марта 2012

Нет;как только тип перечисления завершен, вы не можете его расширить:

enum Blarney { Kirkpatrick, Donegal, Ireland };

enum Blarney { Eire = 3 };  // Not allowed!

На одном уровне обходного пути для него не существует.На другом уровне вы можете просто использовать int значения для хранения элементов из перечисления:

enum Blarney { Kirkpatrick, Donegal, Ireland };
enum BlarneyX { Eire = 3 };

void function(void)
{
    enum Blarney b = Kirkpatrick;
    int y = Kirkpatrick;

    y = Eire;
    y = Donegal;
    switch (y)
    {
    case Kirkpatrick:
    case Donegal:
         printf("Something\n");
         break;
    case Eire:
         printf("Different\n");
         break;
    }

    switch (b)
    {
    case Kirkpatrick:
         printf("Kirkpatrick\n");
         break;
    case Donegal:
         printf("Donegal\n");
         break;
     }
     ...
}

Компилятор может предупредить вас о пропущенном регистре Ireland во втором switch;это не может быть сделано с первым.

2 голосов
/ 16 марта 2012

Нет.Как уже говорили, перечисление C - это время компиляции.

В некоторых языках, таких как Javascript, вы можете создавать объекты, которые рассматриваются как перечисления.Например:

var Colors = { "Red":0xf00, "Blue":0x00f, "Green":0x0f0 };
Colors["Cyan"]=0x0ff;

var bgColor = Colors.Red;

Если вам нужно смоделировать этот метод сопоставления строк со значениями в C (не в C ++), вам потребуется какой-то вид дерева или хеш-таблицы, которая не является частью стандарта Cбиблиотека.В C ++ просто используйте std::map<std::string, int>.

1 голос
/ 16 марта 2012

Нет, вы не можете добавить к 'enum', потому что значения могут быть заменены константами при компиляции модуля перевода, использующего эти значения, в зависимости от параметров отладки, оптимизации и т. Д. Кроме того, что может ссылаться новые значения в уже скомпилированном модуле перевода? Вам придется перекомпилировать.

1 голос
/ 16 марта 2012

Что ты имеешь в виду под словом "как только оно было создано"?Перечисления типов , которые «создаются» во время компиляции.Но поскольку все перечисления имеют одно и то же «пространство имен» (концепция, которой нет в C), вы можете объявить другие перечисления независимо.Тем не менее, вы не можете «переопределить» перечисление.

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