Ошибка со связанным списком структур в Keil

Я работал над своим проектом, и код, который я разместил ниже, успешно работал в Dev C вместе с O/P. Однако Keil выдает ошибки, которые я, к сожалению, не смог определить.

Некоторые образцы:

8051TEST.C(322): предупреждение C198: sizeof возвращает ноль

8051TEST.C(324): ошибка C230: 'switc': неизвестный тег struct/union/enum

8051TEST.C(324): ошибка C204: «s0»: неопределенный элемент

8051TEST.C(325): ошибка C230: 'switc': неизвестный тег struct/union/enum

8051TEST.C(325): ошибка C204: «s1»: неопределенный элемент

8051TEST.C(326): ошибка C230: 'switc': неизвестный тег struct/union/enum

Очень хотелось бы свежей пары глаз.

Спасибо, Аврелий

 typedef struct
 {
 int s0;
 int s1;
 int s2;
 int s3;
 int c;
 int name_len;
 int struct_size;
 char sw_name[10]; //variable length array must be last.
 }switc;

 //Memory allocation and initialisation of structure
 struct switc *createsw(struct switc *s, int id1, int id2, int id3, int id4, 
 int id5, char a[])
 {
s = malloc( sizeof(*s) + sizeof(char) * strlen(a) );

s->s0 = id1;
s->s1 = id2;
s->s2 = id3;
s->s3 = id4;
s->c = id5;
s->name_len = strlen(a);
strcpy(s->sw_name, a);

s->struct_size = ( sizeof(*s) + sizeof(char) * strlen(s->sw_name) );

return s;    
}

  struct newcard //create your own configuration
    {
  int pos_sw1;
  int pos_sw2;
  int pos_sw3;
  int pos_sw4;
  int pos_sw5;
  int pos_sw6;
  int pos_sw7;
   };

 struct newcard *createcard(struct newcard *c, int sr1, int sr2, int sr3, 
 int sr4, int sr5, int sr6, int sr7)
 {
c = malloc( sizeof(*c));

c->pos_sw1 = sr1;
c->pos_sw2 = sr2;
c->pos_sw3 = sr3;
c->pos_sw4 = sr4;
c->pos_sw5 = sr5;
c->pos_sw6 = sr6;
c->pos_sw7 = sr7;
return c;    
}

Мой int main() по запросу. Какая-то мешанина, так что извините заранее. Все это работало безупречно в Dev C.

  int main()
{
Lcd4_Init();
Lcd4_Clear();
switc *s1, *s2, *s3, *s4, *s5, *s6 , *s7;
int id1[5],id2[5],id3[5],id4[5],id5[5],id6[5],id7[5],pos=3;
int cd1[7],cd2[7],cd3[7],cd4[7],cd5[7],cd6[7],sw1=0,sw2=0,sw3=0,sw4=0,sw5=0,
sw6=0,s
  w7=0,card=0,menu=0,n=7;
  int *cd7=(int *)malloc(n * sizeof(int));

M:menu=main_menu();

if(menu==1)//menu to monitor functions
{
 confsel();
 goto M;    
}

//assign number to card based on option selected.
if(menu==2){
card=cardsel();
}

if(menu==3)//Mini info guide 
{
 printf("\nPCB for 6x8 through(SW 1,2,3,4,5,7) + 1x11 through(SW 6) ROTARY SWITCH(s).\n");
 printf("\nSwitch LAYER(s) by 1:8 and 1:16 DEMUX.\n");
 printf("\nTRIGGER to DEMUX(s) by 8255A-5 PPI.\n");
 printf("\nAT89C51RD2 powering device.\n");
 printf("\nEnter card when PROMPTED.\n");
 printf("\nCOOLING FAN provided.\n");
 printf("\nPOTENTIOMETER P(1-5) must be ANTI-CLOCKWISE.\n");
 goto M;    
}

switch(card)
   {
   case 1:
  printf("Power Card assigned\n");
    memcpy(cd1,&pcard,sizeof(cd1));
    sw1=cd1[0];
    sw2=cd1[1];
    sw3=cd1[2];
    sw4=cd1[3];
    sw5=cd1[4];
    sw6=cd1[5];
    sw7=cd1[6];
  break;
case 2:
  printf("Firing Card assigned\n");
    memcpy(cd2,&fcard,sizeof(cd2));
    sw1=cd2[0];
    sw2=cd2[1];
    sw3=cd2[2];
    sw4=cd2[3];
    sw5=cd2[4];
    sw6=cd2[5];
    sw7=cd2[6];
  break;
case 3:
  printf("Const. Curr. Card assigned\n");
    memcpy(cd3,&c1card,sizeof(cd3));
    sw1=cd3[0];
    sw2=cd3[1];
    sw3=cd3[2];
    sw4=cd3[3];
    sw5=cd3[4];
    sw6=cd3[5];
    sw7=cd3[6];
  break;
case 4:
  printf("Const. Curr. 2 Card assigned\n");
    memcpy(cd4,&c2card,sizeof(cd4));
    sw1=cd4[0];
    sw2=cd4[1];
    sw3=cd4[2];
    sw4=cd4[3];
    sw5=cd4[4];
    sw6=cd4[5];
    sw7=cd4[6];
  break;
case 5:
  printf("Amplifier Card assigned\n");
    memcpy(cd5,&acard,sizeof(cd5));
    sw1=cd5[0];
    sw2=cd5[1];
    sw3=cd5[2];
    sw4=cd5[3];
    sw5=cd5[4];
    sw6=cd5[5];
    sw7=cd5[6];
  break;
case 6:
  printf("NC (ATM) Card assigned\n");
    memcpy(cd6,&nccard,sizeof(cd6));
    sw1=cd6[0];
    sw2=cd6[1];
    sw3=cd6[2];
    sw4=cd6[3];
    sw5=cd6[4];
    sw6=cd6[5];
    sw7=cd6[6];
  break;
case 7:
  printf("Custom Card assigned\n");
    incdec(cd7,n);//function to extract values to cd7[] 
    struct newcard *c1;
    c1=createcard(c1,*(cd7 + 0),*(cd7 + 1),*(cd7 + 2),*(cd7 + 3),*(cd7 + 4),*(cd7 + 5),*(cd7 + 6));    
    sw1=c1->pos_sw1;
    sw2=c1->pos_sw2;
    sw3=c1->pos_sw3;
    sw4=c1->pos_sw4;
    sw5=c1->pos_sw5;
    sw6=c1->pos_sw6;
    sw7=c1->pos_sw7;
  break; 
default:
  printf("Invalid Card assigned\n");
  break;
  }

Подпрограммы меню по запросу.

   int main_menu()
  {
const char Main_Menu [3][11] = 
  {
        "1.CONFIG",//TBD
        "2.LOAD",//load PRELOADED_CARD or create CUSTOM_CARD 
        "3.INFO"//check temp/voltage/credits
  };
int menu=0,j=0,i=0;
Lcd4_Set_Cursor(1,3);
M:Lcd4_Write_String("Select your option:");
Lcd4_Set_Cursor(2,4);
Lcd4_Write_String(Main_Menu[j]);

do{
if(RK==0&&j<3)//Right Key
 {
j++;
if(j>=0||j<3)
 {
Lcd4_Set_Cursor(2,4);
Lcd4_Write_String(Main_Menu[j]);
 }
 }

if(LK==0&&j>0)//Left Key
 {
 j--;
 if(j>=0||j<3)
  {
  Lcd4_Set_Cursor(2,4);
  Lcd4_Write_String(Main_Menu[j]);
  }
  }

 if(UK==0)//Up Key
 {
 goto M;
 }

if(EK==0)//Enter Key
 {
if(j>=0||j<3)
 {
menu=j+1;
i=1;
 }
 }

return menu;
 }while(i!=1);  
 }

Сообщения об ошибках по запросу (как только int main запускается, все идет под откос.)

8051TEST.C(464): ошибка C141: синтаксическая ошибка рядом с «переключателем»

8051TEST.C(464): ошибка C202: 's1': неопределенный идентификатор

8051TEST.C(465): ошибка C141: синтаксическая ошибка рядом с «int»

8051TEST.C(465): ошибка C202: 'id1': неопределенный идентификатор

8051TEST.C(466): ошибка C141: синтаксическая ошибка рядом с «int»

8051TEST.C(466): ошибка C202: 'cd1': неопределенный идентификатор

8051TEST.C(467): ошибка C141: синтаксическая ошибка рядом с «int»

8051TEST.C(467): ошибка C202: 'cd7': неопределенный идентификатор

8051TEST.C(469): ошибка C202: «меню»: неопределенный идентификатор

8051TEST.C(471): ошибка C202: «меню»: неопределенный идентификатор

8051TEST.C(478): ошибка C202: «меню»: неопределенный идентификатор

и еще 200 таких C202.


person aurelius    schedule 13.10.2017    source источник
comment
struct switc -> switc. Вы не можете комбинировать typedef и явно печатать struct.   -  person Lundin    schedule 13.10.2017
comment
Кстати, при публикации кода на SO убедитесь, что он правильно отформатирован и имеет отступ. Этот код совершенно нечитаем.   -  person Lundin    schedule 13.10.2017
comment
Извините за беспорядок, но основная программа довольно обширна.   -  person aurelius    schedule 13.10.2017
comment
Либо ваша программа main() имеет правильный отступ, либо нет, независимо от того, насколько она длинная.   -  person Lundin    schedule 13.10.2017
comment
Перестаньте передавать аргументы, которые не используются и сразу перезаписываются. Просто используйте вместо этого локальную переменную.   -  person unwind    schedule 13.10.2017
comment
Что это за M:menu штука, которую ты используешь? Не очень похоже на С.   -  person Gerhardh    schedule 13.10.2017
comment
Он используется для переключения между опциями в меню.   -  person aurelius    schedule 13.10.2017
comment
И что это? Какой-то статический объект C++? M: не является допустимым синтаксисом C.   -  person Gerhardh    schedule 13.10.2017
comment
Я использую простой оператор goto для переключения между меню. Я добавил интерфейс главного меню в качестве примера.   -  person aurelius    schedule 13.10.2017
comment
Обратите внимание, что ни Dev C, ни Keil не являются компиляторами. Я не уверен, что относится к Dev C, но предположительно Dev C++, который является IDE, обычно используемой с MinGW GCC, в то время как Keil — компания, которая производит инструменты разработки для ряда целей. При указании инструментов полезно быть точным, указывать компилятор, а не IDE или поставщика, и включать номера версий. Однако в этом случае ваша ошибка очевидна, и я сомневаюсь, что этот код действительно скомпилирован каким-либо компилятором.   -  person Clifford    schedule 13.10.2017
comment
Обратите также внимание на то, что в сообщениях компилятора указывается номер строки с ошибкой — вы могли бы помочь, указав хотя бы номер строки начала каждого фрагмента.   -  person Clifford    schedule 13.10.2017


Ответы (2)


Когда вы typedef создаете структуру, вам нужно только имя switc, поэтому либо не определяйте его, либо не используйте struct switc для переменной/параметров.

person cleblanc    schedule 13.10.2017
comment
Я использую switc как в // switc *s1, *s2, *s3, *s4, *s5, *s6, *s7; в int main, но я получаю сообщение об ошибке C202: 's1': неопределенный идентификатор - person aurelius; 13.10.2017
comment
@aurelius Я не вижу твоего int main(). Опубликовать? - person cleblanc; 13.10.2017
comment
@aurelius опубликуйте свой код, а не описывайте его. Прочтите это: Как спросить и это минимальный воспроизводимый пример. - person Jabberwocky; 13.10.2017
comment
Добавлен int main(). Извините за беспорядок, но основная программа довольно большая. Используемый микроконтроллер p89v51rd2. - person aurelius; 13.10.2017
comment
@aurelius Если main(...) находится в другом файле, вы должны определить структуру в заголовке и включить ее в оба файла, в противном случае убедитесь, что структура определена ДО вашей основной функции. Обычно я предпочитаю помещать main в конец файла, это логично. - person cleblanc; 13.10.2017
comment
Main находится в том же файле, что и struct. Только заголовочные файлы для ЖКИ и микроконтроллера даны отдельно. Проблема в том, что Keil отказывается подтверждать идентификаторы 8051TEST.C(571): ошибка C202: 'sw6': неопределенный идентификатор 8051TEST.C(572): ошибка C202: 'sw7': неопределенный идентификатор, тогда как все это работало в Dev C с 0 ошибок. - person aurelius; 13.10.2017
comment
@aurelius Поверьте мне, проблема в коде, а не в Кейле. - person cleblanc; 13.10.2017
comment
Использование switc должно быть правильным, но эта строка неверна: struct switc *createsw(struct switc *s,..., так как struct switc не определено. - person Gerhardh; 13.10.2017
comment
Какие-нибудь инсайты тогда? У меня все это разваливается на нексусе указателя структуры переключателя. Есть ли в Keil другой способ объявления связанных списков? - person aurelius; 13.10.2017
comment
Если нет struct switc, не определено *s и, следовательно, нет s->s1 и т. д. Сообщение об ошибке очень точно указывает на это. - person Gerhardh; 13.10.2017
comment
Но есть целая структура, объявленная с помощью typedef struct{}switc; - person aurelius; 13.10.2017
comment
@aurelius Возможно, вы скомпилировали код как нестандартный C++ в Dev C++, а не как стандартный C? Кстати, Dev C++ примерно так же устарел, как 8051, вы должны получить лучший набор инструментов для ПК. Я бы рекомендовал Codeblocks с последним компилятором GCC/Mingw. - person Lundin; 13.10.2017
comment
@Lundin Это определенно показывает его возраст, но для этого проекта подходит 8051. В любом случае, как мне объявить структуру переключателя так, чтобы логика была истинной в int main(). Мне действительно нужны эти * s1, * s2 для моего вывода на мой PPI. - person aurelius; 13.10.2017
comment
Но есть целая структура, объявленная с помощью typedef struct{}switc; Эта структура не имеет имени. Поэтому struct switc недействителен. - person Gerhardh; 13.10.2017
comment
@aurelius Мой комментарий в основном указывал на то, что Dev C ++ устарел и устарел - он больше не поддерживается. Вы можете получить Codeblocks с Mingw бесплатно, codeblocks.org/downloads/binaries. Он поставляется с довольно новой версией GCC (которую при желании можно обновить вручную) и гораздо лучшим отладчиком, чем дрянной в Dev C++. - person Lundin; 13.10.2017
comment
@aurelius Что касается замены на 8051, они не бесплатны ... ARM Cortex M0 может стоить до 2 долларов! Но, к сожалению, вы не можете использовать его в качестве подставки для книг, как вы могли бы с DIP-пакетами 8051 :) Однако это может понравиться любителям сквозных отверстий. - person Lundin; 13.10.2017
comment
Я использовал GCC. Лучше, чем Keil, и бесплатно за 64k. - person aurelius; 13.10.2017
comment
@aurelius Dev C++ использует очень устаревшую версию GCC, которой от 10 до 15 лет. - person Lundin; 13.10.2017
comment
@Lundin Так что здесь есть небольшие сомнения. Я сделал, как было сказано, но все еще получаю синтаксическую ошибку в int main(). Какие-либо предложения? Switc не связан со структурой Typedef. - person aurelius; 13.10.2017

В основном ответ cleblanc упоминает об этом, но я хочу сделать это немного более ясным.

Определение структуры и typedef используется неправильно:

Что вы используете:

typedef struct /* IMPORTANT: NO TAG HERE! */
{
 int s0;
 int s1;
 ...
} switc;

Определенные типы: switc

Допустимое использование:

switc *s1, *s2, *s3, *s4, *s5, *s6 , *s7;
s1->s1 = ...;

Недопустимое использование:

struct switc *s;
s->s1 = ...;

Что, по вашему мнению, вы используете:

typedef struct switc /* NOTE: STRUCT WITH TAG. */
{
 int s0;
 int s1;
 ...
} switc;

Определенные типы: struct switc и switc

Допустимое использование:

switc *s1, *s2, *s3, *s4, *s5, *s6 , *s7;
s1->s1 = ...;
struct switc *s;
s->s1 = ...;

РЕДАКТИРОВАТЬ:

Для вашей основной функции ситуация иная. Здесь компилятор не жалуется на неизвестный тип switch. Вместо этого компилятор недоволен вашим телом функции.

int main()
{
  Lcd4_Init();
  Lcd4_Clear();
  switc *s1, *s2, *s3, *s4, *s5, *s6 , *s7;

До стандарта C99 было обязательно размещать все определения переменных в верхней части тела функции. Если в некоторых комментариях упоминалось, что Keil Dev C - это довольно старый стиль, я ожидаю, что он поддерживает только K&R и C89. (Последний раз я использовал компилятор Keil C для C16x в 2006 году. В то время не было поддержки C99.)

Вы нарушаете это правило, вызывая сначала некоторые LCD4_... функции. Поскольку после этого определения переменных не допускаются, имя типа также не допускается.

Чтобы это исправить, просто измените порядок строк:

int main()
{
  switc *s1, *s2, *s3, *s4, *s5, *s6 , *s7;
  Lcd4_Init();
  Lcd4_Clear();
person Gerhardh    schedule 13.10.2017
comment
Большое спасибо за ответ. Одно малюсенькое сомнение. Я все еще получаю эти ошибки при переключении в int main() даже после действительного использования. 8051TEST.C(463): ошибка C141: синтаксическая ошибка рядом с «switc» 8051TEST.C(463): ошибка C202: «s1»: неопределенный идентификатор 8051TEST.C(464): ошибка C141: синтаксическая ошибка рядом с «int» 8051TEST. C(464): ошибка C202: 'id1': неопределенный идентификатор 8051TEST.C(465): ошибка C141: синтаксическая ошибка рядом с 'int' - person aurelius; 13.10.2017
comment
Определен ли main() в том же файле, что и switc, или эти 2 фрагмента из разных файлов? - person Gerhardh; 13.10.2017
comment
main_menu() — это функция меню - person aurelius; 13.10.2017
comment
Я спрашивал о main, где вы получаете сообщения об ошибках синтаксиса. - person Gerhardh; 13.10.2017
comment
Да, int main() — это место, где начинается время выполнения основной программы. - person aurelius; 13.10.2017
comment
Каким образом это могло бы ответить на мой вопрос? ГДЕ это определяется? Тот же файл или другой файл? - person Gerhardh; 13.10.2017
comment
тот же файл. основной () - person aurelius; 13.10.2017
comment
Пожалуйста, покажите точные сообщения об ошибках и укажите, к каким строкам в вашем фрагменте они относятся. - person Gerhardh; 13.10.2017
comment
Подождите... Тот же файл, что и main_menu, или тот же файл, что и определение switc? - person Gerhardh; 13.10.2017
comment
Там один файл только 8051test или как там. Этот переключатель представляет собой отдельную структуру, и главное меню просто вызывается на основе имеющегося у него списка константных символов. - person aurelius; 13.10.2017
comment
Главное меню Goto Boondongle просто позволяет переключаться между меню. - person aurelius; 13.10.2017
comment
M: это просто оператор goto для запуска функции main_menu(). Ошибки начинаются со строки *s1,*s2..... во фрагменте №2. В основном компилятор не распознает структуру typedef... switc с switc *s1,*s2. - person aurelius; 13.10.2017
comment
какие-либо предложения? - person aurelius; 13.10.2017
comment
@aurelius О боже! Прошу прощения, я был как-то слеп. Какой стандарт C поддерживается? C89 не допускает определения переменных после других операторов. Переместите вызовы в Lcd4_* после определений. Действительно ли в вашем коде есть разрыв строки внутри s w7? - person Gerhardh; 13.10.2017
comment
И я также был немного ослеплен этим лейблом. Перепутал с :: из C++. Простите за это - person Gerhardh; 13.10.2017
comment
@aurelius есть улучшения? - person Gerhardh; 17.10.2017