|
Вопрос скорее по Си |
|
|
|
Jun 1 2007, 15:17
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
В программе объявлен такой тип данных Код #define MAX_DATA_SIZE 128 struct TStructure { unsigned char DataSize;// размер данных unsigned char Data[MAX_DATA_SIZE]; }; Соответственно есть переменные такого типа: Код struct TStructure st1={ 3, {1,2,3} }; struct TStructure st1={ 1, {1} }; Структуры должны хранится в программной памяти и загружаться в ОЗУ соответственно ситуации. Проблема в том, что Data может быть разной длины (от 1 до 128), то есть программная память зря расходуется. Как определить структуру, чтобы поле Data имела размер не больше чем требуется?
|
|
|
|
|
Jun 1 2007, 15:28
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
ИМХО, забейте на эту структуру!  Объявите одномерный массив Код unsigned char Data[MAX_DATA_SIZE+1]; И интерпретируйте его первый элемент (Data[0]) как валидный размер текущего массива. Соответственно ваши данные располагайте, начиная со второго элемента массива (Data[1]). P.S. я понимаю, когда в структуру объединяют разнотипные данные, но зачем для однотипных структуру-то создавать? Если только для того чтобы "красиво" в тексте исходника выглядело, дык дефайны для этого имеются, типа Код #define DataSize Data[0]
|
|
|
|
|
Jun 1 2007, 15:44
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(rezident @ Jun 1 2007, 18:28)  P.S. я понимаю, когда в структуру объединяют разнотипные данные, но зачем для однотипных структуру-то создавать? Если только для того чтобы "красиво" в тексте исходника выглядело, дык дефайны для этого имеются, типа Код #define DataSize Data[0] Данные разнотипные (пример неудачный). В Паскале я бы написал так: Код type Tstructure=record A: Byte; B: array of TDateTime;// TDateTime для примера end; На Си что-то не придумывается (хотя преложенный вариант в принципе подходит).
|
|
|
|
|
Jun 1 2007, 16:23
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
IMHO, лучше массивы не пытаться укладывать в структуры, ибо их размер должен быть определен. Лучше уж примерно так:
typedef struct TStructure { unsigned char DataSize;// размер данных unsigned char * pData; //указатель на начало массива }TStructure;
unsigned char Data[]={1,2,3,4}; unsigned char Data1[]={1,2,3,4,5,6,7};
TStructure mystr = {sizeof(Data), &Data[0])}; TStructure mystr1 = {sizeof(Data1), &Data1[0])};
--------------------
aka Vit
|
|
|
|
|
Jun 1 2007, 17:17
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(rezident @ Jun 1 2007, 18:28)  ИМХО, забейте на эту структуру!  Совершенно неразумный совет. Цитата И интерпретируйте его первый элемент (Data[0]) как валидный размер текущего массива. Ну зачем, о Господи! Если совершенно естественно именуется поле структуры а уж его "интерпретацией" должен заниматься компилятор. Зачем забивать себе и другим лишними знаниями, соглашениями и потенциальными ошибками. Цитата(_Артём_ @ Jun 1 2007, 19:49)  Пожалуй остановлюсь на массиве. И, простите, как, это поможет проблеме??? Внимательно читайте пост defunct - Ваш вариант это динамическое выделение памяти.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 1 2007, 17:50
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Наверное присоединюсь к defunct и zltigo. И структура здесь не мешает. Хотя я бы всёже в структуру вводил ссылку на массив и его длину. Со строками пример приведу, а массив ничем по сути не отличается. Код struct AddrKom_e { uint8_t Name; // Имя команды uint16_t TimeStart; // Время начала исполнения команды uint8_t TimeRealH; // Время реальное часы uint8_t TimeRealM; // Время реальное минуты } *Kom_e;
struct AddrKomT { uint8_t Name; // Имя команды uint16_t TimeStart; // Время начала исполнения команды uint8_t TimeMashtabTek, // Текущее значение масштаба для времени исполнения TimeMashtab; // Масштаб для времени исполнения uint16_t TimeLife; // Время исполнения команды с учётом масштаба int16_t BegX,BegY; // Начало объекта (X,Y) int8_t VecX,VecY; // вектор перемещения объекта (X,Y) uint8_t text[10]; // Текст сообщения } *KomT;
struct AddrKomR { uint8_t Name; // Имя команды uint16_t TimeStart; // Время начала исполнения команды uint8_t TimeMashtab; // Изменение масштаба для времени исполнения uint16_t TimeLife; // Изменение времени исполнения команды с учётом масштаба int16_t BegX,BegY, // Изменение начала объекта (X,Y) SizeX,SizeY; // Изменение размеров объекта (X,Y) int8_t VecX,VecY; // Изменение вектора перемещения объекта (X,Y) uint8_t NAktive; // Номер изменяемого объекта } *KomR;
..... А применяю так Код KomXx = (struct AddrKomXx*) AdrActiveKom[i]; // Прочитать адрес текущей активной команды if(KomXx->TimeStart>Status.TekTime) continue; // Если не подошло время для исполнения команды, то пропустить данную команду switch (KomXx->Name) { /* Команда "END" - "Ролик завершить" */ case 'E': ...... case 'e': Kom_e = (struct AddrKom_e*) AdrActiveKom[i];// Прочитать адрес текущей активной команды if((Kom_e->TimeRealH>Status.Hour)&&(Kom_e->TimeRealM>Status.Minute)){ .....
|
|
|
|
|
Jun 1 2007, 18:20
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(defunct @ Jun 1 2007, 18:48)  Как вариант - использовать "open array" и динамическое выделение памяти: Вот только с выделением облом - автор хотел эти структуры во флеше хранить. Т.е. если использовать "incomplete arrays" (в терминологии стандарта), то должно получиться: Код typedef struct { uint8_t size; uint8_t data[] } my_struct_type; my_struct_type const __flash Struct = { 2, { 1, 2} }; Только надо помнить четыре вещи: 1)такой массив может располагаться только в конце структуры 2)sizeof() будет выдавать размер такой структуры без учета массива, т.е. в данном случае 1 и сделать массив из таких структур уже не получится, а также арифметика указателей на этих структурах будет работать некорректно. 3) не все компиляторы поддерживают incomplete arrays (ИАР поддерживает) 4) В С++ такое уже не прокатит.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 1 2007, 18:43
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(zltigo @ Jun 1 2007, 23:17)  Совершенно неразумный совет. Вы как всегда категоричны  Чем же он неразумен в применении к структуре однотипных переменных? Структура это всего лишь абстракция, предназначенная для удобства человека. Чтобы человек-программист мог на привычном для него объектном уровне изложить компилятору свою точку зрения на вид, размерность и порядок расположения переменных. Данные в памяти будут все равно в виде байтов, 16-ти или 32-разрядных слов располагаться, в соответствии со способом организации типа памяти конкретного МК. Цитата(zltigo @ Jun 1 2007, 23:17)  Ну зачем, о Господи! Если совершенно естественно именуется поле структуры а уж его "интерпретацией" должен заниматься компилятор. Собственно я об этом же, только без обращения к Творцу  Только зачем она в приведенном автором топика примере? Цитата(zltigo @ Jun 1 2007, 23:17)  Зачем забивать себе и другим лишними знаниями, соглашениями и потенциальными ошибками. Тогда нужно на Паскале писать, а не на Си. Делов-то! Цитата(zltigo @ Jun 1 2007, 23:17)  Внимательно читайте пост defunct - Ваш вариант это динамическое выделение памяти. Читайте пост Сергея Борщ о том, какие проблемы бывают с незавершенными массивами.
|
|
|
|
|
Jun 1 2007, 21:24
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(rezident @ Jun 1 2007, 21:43)  Читайте пост Сергея Борщ о том, какие проблемы бывают с незавершенными массивами. Вам бы тоже не помешало прочитать его пост и сравнить два термина "open array" и "incomplete array". Проблемы перечисленные Сергеем не распространяются на open array, кроме одной - Цитата 1)такой массив может располагаться только в конце структуры Ну а то что нельзя разместить во флеш - да.. Но в контексте AVR - флеша ведь в разы больше чем RAM'а, для чего могла потребоваться такая экономия?! Цитата(Сергей Борщ @ Jun 1 2007, 21:20)  Вот только с выделением облом - автор хотел эти структуры во флеше хранить. Во флеш можно хранить в удобном и нормальном для этого виде, также как у автора ветки - структуры фиксированной длинны. Экономия на мой взгляд может потребоваться во второй части задачи - "загружаться в ОЗУ соответственно ситуации." Вот тут как раз сэкономить поможет способ с дин. выделением памяти.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|