Структура как правильно?

есть набор полей обьедененых в структуру.
нужно использовать скажем 20 полей (грубо говоря таблица)
обьявляю так.

menu.h

#include "main.h"


typedef volatile struct {
        uint8_t adr_eep;
	char list[20];

} list_eept;

menu.c

#include "menu.h"
#include "keys.h"
#include "s_var.h"

 list_eept list_eep[20]={0};  

void list_sort(uint8_t nn)
{
	list_eep[0].adr_eep=0;
	memset(list_eep[0].list,'0',20);

   list_eep[1].adr_eep=0x12;
   strcpy(list_eep[1].list,'HELLO');

}



}

Подскажите пожалуйста ,
1.Нужно ли указывать в структуре в файле menu.h строка 8 - } list_eept[20]
2. строка 20 menu.c правомерна ли запись list_eept list_eep[20]={0}; для инициализации всей структуры 0 ? или использовать код , как в строках 9-10?
Спасибо.

Сам компилятор не ругается ни на такой код , ни на такой про который спрашиваю…

Зачем?

Зачем? Зачем её нулями инициализировать? У вас с этим какие-то проблемы могут быть?

ЗЫ: Чтобы не было путанице (как у вас сейчас), разделяйте именование типов и имена переменных.
Например:

typedef volatile struct {
        uint8_t adr_eep;
	char list[20];

} List_EEpt;

List_EEpt list_eep[20];

Ну в начале наверное нет , хотя не понятно, что там будет при старте (вроде без инициализации там может быть мусор ), но потом нужно таблицу время от времени обнулять…

Я понял спасибо

Опять таки - зачем?
Может быть у вас ошибка в проектировании?
Нужно ли обнулять кольцевой буфер при каждом «проходе»?

возможно…
первый цикл - заполняется таблица с датчиков … записывается с нее во флешь .
второй цикл тоже самое… в какой-то момент выбираешь номер цикла и данные с флешь заносятся в таблицу…
Между первым и вторым циклом желательно таблицу очистить т.к заполнятся может не вся …

Если переменная (массив структур) объявляется глобально и не инициализируется при объявлении, то компилятор по умолчанию инициализирует ее значением 0.
А вот если локально, то там да без пользовательской инициализации будет лежать всякий мусор.

1 лайк

Это разные вещи. Можно и так, и эдак. А что Вам нужно, никто, кроме Вас, не знает. Главное, чтобы Вы понимали разницу между этими записями и использовали то, что Вам нужно.

Вы правы . я и пытаюсь понять в чем разница между

и

Если не трудно обьясните пожалуйста.

Вообще-то код в строчках 9-10 совершенно не эквивалентен инициализации структуры в начале кода, тут вы заполняете массив символом нуля, а не нулем.

Да, но это уже предсказуемое значение, а не мусор .

Скорее бесполезное.

1 лайк

Просто новый тип и масссив новых типов (нахуа?)…

Если вы пытаетесь “очистить” символьный массив, то так неправильно. В строке должен быть терминатор, а у вас его нет.
Для очистки символьного массива достаточно поставить ноль (\0) в нулевой позиции.

Ну, дык, я думал Вы знаете

//
// Ниже описан тип с именем List_EEpt
// Каждая переменная этого типа является массивом из 20 элементов.
// при этом каждый элемент имеет вид
//       volatile struct {
//             uint8_t adr_eep;
//             char list[20];
//       }
// Переменная занимает в памяти 420 байтов, в чём легко убедиться
// выполнив: Serial.println(sizeof(List_EEpt));
//
typedef volatile struct {
        uint8_t adr_eep;
	char list[20];

} List_EEpt[20];

/////////////////////////////////////////////////////////
//
// Ниже описан тип с именем List_EEpt1
// Каждая переменная этого типа является структурой
//       volatile struct {
//             uint8_t adr_eep;
//             char list[20];
//       }
// Переменная занимает в памяти 21 байт в чём легко убедиться
// выполнив: Serial.println(sizeof(List_EEpt1));
//
typedef volatile struct {
        uint8_t adr_eep;
	char list[20];

} List_EEpt1;

Ну, вот, как-то так. Т.е. первый тип – это массив фиксированной длины. А второй тип – структура.

Обычно тип для массива (первый вариант) описывают тогда, когда массив всегда имеет фиксированную длину и она никогда не меняется (или когда важно, чтобы тип имел “правильный” sizeof, например, такая ситуация описана вот здесь, где я требую описывать “массивный тип”). В случае, когда массив может иметь любую длину, описывают тип элемента (второй вариант), а при объявлении переменной дописывают размерность массив в квадратных скобках.

Вот, смотрите:

//
// Тип - массив структур фиксированной длины
//
typedef struct {
   uint8_t pinA;
   uint8_t pinB;
} TKaka[20];

//
// Тип - одиночная структура
//
typedef struct {
   uint8_t pinA;
   uint8_t pinB;
} TMumu;

TKaka kaka; // описали массив длины 20 (она зафиксирована в типе)
TMumu mumu[20]; // описали массив длины 20 (указали прямо здесь)

Здесь переменные kaka и mumu одинаковые. И та, и другая - массив структур длины 20 (можете проверить sizeof’ом). Просто тип TKaka всегда описывает массивы длины 20, а тип TMumu описывает только элемент, а массив мы объявляем уже при описании переменной mumu.

1 лайк

если я правильно понял , то typedef volatile struct сам тип не создается это просто шаблон… а во List_EEpt list_eep[20]; создает уже 20 … поэтому я в typedef и не писал [20]. но возможно я неправильно понял , поэтому и хотел , чтобы меня поправили если не так

Большое спасибо . Буду вникать в написанное

как это сделать ?
list_eep[0].list=‘\0’; ошибка или также strcpy(list_eep[1].list=‘\0’);?

list_eep[0].list[0]=‘\0’;

1 лайк

Спасибо большое. Я вроде понял… У меня еще один вопрос … Если в Вашем примере

//
// Тип - массив структур фиксированной длины
//
typedef struct {
   uint8_t pinA;
   uint8_t pinB;
} TKaka[20];

//
// Тип - одиночная структура
//
typedef struct {
   uint8_t pinA;
   uint8_t pinB;
} TMumu;

будет
TKaka kaka[20];
Получается 20 массивов из 20 элементов (pinA,pinB) т.е 8400 байт?
На что тогда будет указывать kaka[0]?
Если я правильно понял он тогда должен указать на массив Tkaka состоящий из 20 полей (pinA,pinB) ? Другими словами это будет уже указатель ? Даже если я не использую ‘*’ ?
Как мне в таком случае обратиться допустим к 5-му массиву к 7 строке массива Tкака , к pinA?
кака[5].pinA уже вроде бессмыслица… Или так TKaka kaka[20]; неправильно делать?
Вопрос для общего развития т.к массив массивов я пока не использовал…