Доступ к значениям перечисления, определенного в структуре - PullRequest
2 голосов
/ 01 декабря 2011

Структура struct выглядит следующим образом:

struct padData 
{
    enum buttonsAndAxes
    {
        select,
        start,
        ps
    };
};

Объект struct :

padData        pad;

Я получаю доступ к этому перечислениюследующим образом:

printf ("\n%d", pad.buttonsAndAxes[0]);

Ошибка:

error: invalid use of ‘enum padData::buttonsAndAxes’

Затем я попытался:

printf ("\n%d", pad::buttonsAndAxes[0]);

Ошибка:

error: ‘pad’ is not a class or namespace

Что теперь?Пожалуйста, руководство.

Компилятор: gcc версия 4.5.0

РЕДАКТИРОВАТЬ 1: _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __

printf ("\nemit: %d", padData::(select)0);

приводит к:

error: expected unqualified-id before ‘(’ token

Моя цель - извлечь слово «select» через его значение 0. Как этого достичь?Кроме того, слово "выбрать" строку?

Ответы [ 4 ]

2 голосов
/ 01 декабря 2011
printf ("\n%d", padData::select);

Enum не массив, он используется без индекса.

2 голосов
/ 01 декабря 2011

Значения перечисления становятся именами в области видимости класса. Таким образом, вы должны использовать padData::select вне класса или просто select из класса.

В C ++ 11 вы можете квалифицировать счетчики с именем enum, давая padData::buttonsAndAxes::select снаружи и buttonsAndAxes::select изнутри.


Печать имени перечислителя нелегко сделать в C ++, потому что имена исчезли после компиляции. Вам нужно настроить таблицу, отображающую значения в их строки вручную. Если вы не предоставите явные значения, как в вашем примере, вы можете просто использовать массив:

enum buttonsAndAxes
{
    select,
    start,
    ps
};

const char* buttonsAndAxesNames[] = {
    "select",
    "start",
    "ps"
};

И затем вы индексируете в этот массив:

 printf("%s", buttonsAndAxesNames[select]);

Если вам нужен более сложный подход, вы можете найти несколько хитростей в предыдущих вопросах .

1 голос
/ 01 декабря 2011

Вам, кажется, нужна хорошая книга по C ++.

Перечисления в C и C ++ - это удобный способ:

  • сопоставить целое значение с «умным» именем
  • группирует значения, которые принадлежат друг другу

Синтаксис довольно прост (на C ++ 03):

enum <enum-name> {
  <value-name-0> [= <value-0>],
  <value-name-1> [= <value-1>],
  ...
};

Где:

  • <enum-name> - это имя типа , который вводится
  • <value-name-X> - это имя значения перечисления
  • <value-X> isзначение присваивается имени и является необязательным

Если имени не присваивается значение:

  • , если оно первое, оно устанавливается на 0
  • иначе, ему присвоено значение предыдущего имени, + 1

Вот небольшой пример, демонстрирующий использование перечислений:

enum Color {
  Blue,
  Green,
  Red
};

char const* name(Color c) {
  switch(c) {
  case Blue: return "Blue";
  case Green: return "Green";
  case Red: return "Red";
  }
  assert(0 && "Who stored crap in my enum ?");
}

Это иллюстрирует сразу несколько важных моментов:

  • Color - это тип , подобный типу структуры или типу класса.Он может быть определен как typedef, и все.
  • и enum «имя-значения» является интегральной константой, ее можно использовать в качестве параметра шаблона или в случаях переключения.имя-значения "вводится в область, в которой объявлен тип, а не вложено в нее.(C ++ 11 позволяет охватывать значения с помощью синтаксиса enum class)
  • что-то еще может полностью храниться в enum, хотя это не должно происходить в приложениях с хорошим поведением, вы можете сделать это черезcasting ...

Что не показано, так это то, что enum находится под капотом как простое целое число.Точный базовый тип определяется по усмотрению компилятора.В этом выборе есть несколько правил, которые не должны иметь значения для вас, все, что вы должны знать, - это то, что выбранный тип достаточно широк, чтобы содержать все значения перечисления (и, возможно, подписать, если требуется).Это означает, что выбранный тип не обязательно является простым int.

Следовательно: printf("%d", Green); является ошибкой программирования.Это должно быть printf("%d", (int)Green);.

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

1 голос
/ 01 декабря 2011

ENUMS в основном используются для лучшей читаемости кода, а не для облегчения вычислений. ENUMS - это в основном литералы, которым присваиваются значения 0,1,2 и т. Д., Если не указано иное. Поэтому вы всегда должны использовать их с квалификацией "::", а не как массив

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