Я не уверен в правильности синтаксиса для использования перечислений в C. У меня есть следующий код:
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
Но он не компилируется, выдавая следующую ошибку:
error: conflicting types for ‘strategy’
error: previous declaration of ‘strategy’ was here
Что я делаю не так?
Это's стоит отметить, что вы Don'т нужны а тип
. Вы можете просто сделать это, как следующие
enum strategy { RANDOM, IMMEDIATE, SEARCH };
enum strategy my_strategy = IMMEDIATE;
Это's вопрос стиля, предпочитаете ли вы тип
. Без этого, если вы хотите ссылаться на тип перечисления, вы должны использовать стратегии перечисление`. С его помощью вы можете просто сказать "стратегии".
Оба пути имеют свои преимущества и недостатки. Одним из них является более многословны, но держит тип идентификаторов в тег-пространство имен, в котором они выиграли'т конфликтует с обычными идентификаторами (вспомните структура стат
и стат
назначение: Дон'т конфликта либо), и где вы сразу увидите, что это'ы тип. Другая-короче, но приносит идентификаторы типа в обычном пространстве имен.
Объявление переменной enum выполняется следующим образом:
enum strategy {RANDOM, IMMEDIATE, SEARCH};
enum strategy my_strategy = IMMEDIATE;
Однако вы можете использовать typedef
, чтобы сократить объявление переменной, например, так:
typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy my_strategy = IMMEDIATE;
Наличие соглашения об именовании для различения типов и переменных - хорошая идея:
typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy_type;
strategy_type my_strategy = IMMEDIATE;
Вы'вновь пытается объявить "стратегия" два раза, и что's, почему вы'вновь получаю выше сообщение об ошибке. Следующие работы без каких-либо нареканий (скомпилированные с помощью GCC -ANSI в -pendantic -стена):
#include <stdio.h>
enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE;
int main(int argc, char** argv){
printf("strategy: %d\n", strategy);
return 0;
}
Если вместо выше второй линии были изменены:
...
enum { RANDOM, IMMEDIATE, SEARCH } strategy;
strategy = IMMEDIATE;
...
От предупреждения, вы можете легко увидеть вашу ошибку:
enums.c:5:1: warning: data definition has no type or storage class [enabled by default]
enums.c:5:1: warning: type defaults to ‘int’ in declaration of ‘strategy’ [-Wimplicit-int]
enums.c:5:1: error: conflicting types for ‘strategy’
enums.c:4:36: note: previous declaration of ‘strategy’ was here
Поэтому компилятор приняли стратегии = немедленно за объявлением переменной, называется "стратегия" с типом по умолчанию инт
, но там был уже предыдущее объявление переменной с таким именем.
Однако, если вы разместили задание в функции main ()`, он будет действительным код:
#include <stdio.h>
enum { RANDOM, IMMEDIATE, SEARCH } strategy = IMMEDIATE;
int main(int argc, char** argv){
strategy=SEARCH;
printf("strategy: %d\n", strategy);
return 0;
}
Когда вы говорите
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
вы создаете единственную переменную экземпляра 'strategy' безымянного перечисления. Это не очень полезная вещь - вам нужен типизатор:
typedef enum {RANDOM, IMMEDIATE, SEARCH} StrategyType;
StrategyType strategy = IMMEDIATE;
Как написано, там's ничего плохого с вашим кодом. Вы уверены, что вы не'т сделать что-то подобное
int strategy;
...
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
Какие линии делать смысл сообщения об ошибке? Когда он пишет "предыдущей декларации 'стратегия' был здесь", что'ы с "Здесь" и для чего это показывают?
@ThoAppelsin в своем комментарии на вопрос отвечал правильно. Фрагмент кода написал в вопросе, это действительно и без ошибок. Ошибка у тебя, должно быть, потому, что другие плохие синтаксис в любом другом месте вашего c исходный файл. перечисление{А,B,с};
определяет три символьные константы (а
, б
и С
), которые являются целыми числами со значениями 0
,1
и 2
соответственно, но когда мы используем перечисление
это потому, что мы не'т, как правило, заботиться о конкретных целочисленное значение, мы больше заботиться о смысле символическое имя константы.
Это означает, что вы можете иметь это:
#include <stdio.h>
enum {a,b,c};
int main(){
printf("%d\n",b);
return 0;
}
и это будет выход 1
.
Это также будет действителен:
#include <stdio.h>
enum {a,b,c};
int bb=b;
int main(){
printf("%d\n",bb);
return 0;
}
и выход такой же, как и раньше.
Если вы сделаете это:
enum {a,b,c};
enum {a,b,c};
вы увидите сообщение об ошибке, но если вы сделаете это:
enum alfa{a,b,c};
enum alfa;
вы не будете иметь никаких ошибок.
вы можете сделать это:
enum {a,b,c};
int aa=a;
и АА
будет переменная типа integer со значением 0
. но вы также можете сделать это:
enum {a,b,c} aa= a;
и будет иметь тот же эффект (то есть, АА
быть инт
с 0
значение).
вы также можете сделать это:
enum {a,b,c} aa= a;
aa= 7;
и АА
будет инт
со значением 7
.
потому что вы не можете повторить символическое определение константы с использованием перечисление
, как я уже сказал, Вы должны использовать теги если вы хотите объявить как int
Варс с использованием перечисление
:
enum tag1 {a,b,c};
enum tag1 var1= a;
enum tag1 var2= b;
использование оператора typedefэто безопасная тебе писать каждый раз
перечислимые значения tag1, чтобы определить переменную. С помощью typedef можно просто ввести значения tag1
:
typedef enum {a,b,c} Tag1;
Tag1 var1= a;
Tag1 var2= b;
Вы также можете иметь:
typedef enum tag1{a,b,c}Tag1;
Tag1 var1= a;
enum tag1 var2= b;
Последняя вещь, чтобы сказать это, что, поскольку речь идет об определенных символических констант лучше использовать заглавные буквы при использовании перечисление
, например:
enum {A,B,C};
вместо
enum {a,b,c};
Стоит отметить, что в C++ вы можете использовать "enum" для определения нового типа без использования оператора typedef.
enum Strategy {RANDOM, IMMEDIATE, SEARCH};
...
Strategy myStrategy = IMMEDIATE;
Я нахожу этот подход гораздо более дружественным.
[edit - clarified C++ status - I had this in originally, then removed it!]
Там, кажется, путаница в декларации.
Когда стратегии'comes перед {случайное, мгновенное, поиск}
, как в следующем,
enum strategy {RANDOM, IMMEDIATE, SEARCH};
вы создаете новый тип под названием Стратегия перечисление
. Однако, при объявлении переменной, нужно использовать сам перечисление стратегии
. Вы не можете просто использовать "стратегии". Поэтому следующим является недействительным.
enum strategy {RANDOM, IMMEDIATE, SEARCH};
strategy a;
В то время как по
enum strategy {RANDOM, IMMEDIATE, SEARCH};
enum strategy queen = RANDOM;
enum strategy king = SEARCH;
enum strategy pawn[100];
Когда стратегии
идет после {случайные, непосредственные, поиск}
, вы создаете анонимный enum и затем объявив "стратегия" для переменной этого типа.
Так что теперь, вы можете сделать что-то подобное
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = RANDOM;
Однако, вы не можете объявить любой другой переменной типа перечисление {случайное, мгновенное, поиск}
потому что вы никогда не назвали его. Поэтому следующим является недействительным
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
enum strategy a = RANDOM;
Вы можете объединить оба определения
enum strategy {RANDOM, IMMEDIATE, SEARCH} a, b;
a = RANDOM;
b = SEARCH;
enum strategy c = IMMEDIATE;
Определение типа
как отмечалось ранее, используется для создания более короткие переменной.
typedef enum {RANDOM, IMMEDIATE, SEARCH} strategy;
Сейчас вы сказали компилятору, что тип enum {случайное, мгновенное, поиск}становится символом для "стратегии". Так что теперь вы можете свободно использовать "стратегии" как тип переменной. Вы Don'т нужно набирать
стратегии перечисление`. Следующий действует сейчас
strategy x = RANDOM;
Вы также можете комбинировать оператор typedef с именем перечислимого к вам
typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy;
Там's не много преимуществ использования этого метода помимо того, что теперь вы можете использовать стратегии
и перечисление strategyName
взаимозаменяемы.
typedef enum strategyName {RANDOM, IMMEDIATE, SEARCH} strategy;
enum strategyName a = RANDOM;
strategy b = SEARCH;
Если вы объявляете имя для перечисления никакой ошибки не возникнет.
Если не объявлен, вы должны использовать оператор typedef`:
enum enum_name {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
Он не будет отображать сообщение об ошибке...
Мой любимый и используется только в строительстве всегда был:
оператор typedef enum в MyBestEnum { /* достаточно хорошо */ Хороший = 0, /* еще лучше */ Лучше, /* Божественная */ Лучшие };
Я считаю, что это снимет ваши проблемы. Используя новый тип с моей точки зрения правильный вариант.
КАТП'ы ответ является лучшим.
Многое из перечислимого обсуждение-это отвлекающий маневр.
Сравните этот фрагмент кода:-
int strategy;
strategy = 1;
void some_function(void)
{
}
что дает
error C2501: 'strategy' : missing storage-class or type specifiers
error C2086: 'strategy' : redefinition
с этим, который компилируется без проблем.
int strategy;
void some_function(void)
{
strategy = 1;
}
Должен переменную "стратегии" должен быть установлен на заявление или внутри функции и т. д. Вы не можете писать произвольные программы - задания, в частности - на глобальном уровне.
Тот факт, что он используется в enum {случайные, непосредственные, поиск} вместо int используется только в той мере, в которой он запутался человек, что может'т смотрите за его пределами. Переопределение сообщения об ошибках в этом вопросе показывают, что это то, что автор сделал неправильно.
Итак, теперь вы должны быть в состоянии видеть, почему первый пример ниже-это неправильно, а остальные три в порядке.
Пример 1. Неправильно!
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
void some_function(void)
{
}
Пример 2. Право.
enum {RANDOM, IMMEDIATE, SEARCH} strategy = IMMEDIATE;
void some_function(void)
{
}
Пример 3. Право.
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
void some_function(void)
{
strategy = IMMEDIATE;
}
Пример 4. Право.
void some_function(void)
{
enum {RANDOM, IMMEDIATE, SEARCH} strategy;
strategy = IMMEDIATE;
}
Если у вас есть рабочая программа, вы должны просто быть в состоянии, чтобы вставить эти фрагменты в вашу программу и вижу, что некоторые компиляции, а некоторые нет.
Я попытался с ССЗ и придумать для моей потребности я был вынужден использовать последний вариант, чтобы скомпилировать с ошибок.
оператор typedef enum в состоянии {а = 0, Б = 1, с = 2} состояние;
typedef enum state {a = 0, b = 1, c = 2} state;
typedef enum state old; // New type, alias of the state type.
typedef enum state new; // New type, alias of the state type.
new now = a;
old before = b;
printf("State now = %d \n", now);
printf("Sate before = %d \n\n", before);