реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Вопрос скорее по Си
_Артём_
сообщение Jun 1 2007, 15:17
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 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 имела размер не больше чем требуется?
Go to the top of the page
 
+Quote Post
rezident
сообщение Jun 1 2007, 15:28
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



ИМХО, забейте на эту структуру! wink.gif Объявите одномерный массив
Код
unsigned char Data[MAX_DATA_SIZE+1];

И интерпретируйте его первый элемент (Data[0]) как валидный размер текущего массива. Соответственно ваши данные располагайте, начиная со второго элемента массива (Data[1]).
P.S. я понимаю, когда в структуру объединяют разнотипные данные, но зачем для однотипных структуру-то создавать? Если только для того чтобы "красиво" в тексте исходника выглядело, дык дефайны для этого имеются, типа
Код
#define DataSize Data[0]
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jun 1 2007, 15:44
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 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;


На Си что-то не придумывается (хотя преложенный вариант в принципе подходит).
Go to the top of the page
 
+Quote Post
_artem_
сообщение Jun 1 2007, 15:44
Сообщение #4


учащийся
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 29-10-05
Из: города контрастов
Пользователь №: 10 249



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

Наверно Страуструп с этого и начинал)


--------------------
Зачем лаять на караван , когда на него можно плюнуть?

Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 1 2007, 15:48
Сообщение #5


кекс
******

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



Как вариант - использовать "open array" и динамическое выделение памяти:

Код
typedef struct tagMY_STRUCT
{
    U8 size;
    U8 payload[1];
} TMY_STRUCT, *PMY_STRUCT;


{
   PMY_STRUCT pStruct;

   pStruct = (PMY_STRUCT)malloc(...); // столько памяти сколько надо..
   pStruct->size = ...;
..
}
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Jun 1 2007, 16:23
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
rezident
сообщение Jun 1 2007, 16:30
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(_Артём_ @ Jun 1 2007, 21:44) *
Данные разнотипные (пример неудачный).

Вы сами такой пример написали wink.gif Откуда я могу предполагать что у вас на уме использовать другой тип данных для хранения размера буфера?
Цитата(_Артём_ @ Jun 1 2007, 21:44) *
На Си что-то не придумывается (хотя преложенный вариант в принципе подходит).

Для вас ведь важно выделить массив памяти, требуемого размера. А как вы там будете интерпертировать данные в нем это дело десятое - компилятор Си не особо вас здесь ограничивает. В этой части у него явное преимущество перед Паскалем. Правда и напортачить в данных при этом он вам позволит на порядок больше, нежли Паскаль. smile.gif
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jun 1 2007, 16:49
Сообщение #8


Гуру
******

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



Цитата(rezident @ Jun 1 2007, 19:30) *
Вы сами такой пример написали wink.gif Откуда я могу предполагать что у вас на уме использовать другой тип данных для хранения размера буфера?

Для вас ведь важно выделить массив памяти, требуемого размера. А как вы там будете интерпертировать данные в нем это дело десятое - компилятор Си не особо вас здесь ограничивает. В этой части у него явное преимущество перед Паскалем. Правда и напортачить в данных при этом он вам позволит на порядок больше, нежли Паскаль. smile.gif


Пожалуй остановлюсь на массиве.
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 1 2007, 17:14
Сообщение #9


кекс
******

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



Цитата(sensor_ua @ Jun 1 2007, 19:23) *
IMHO, лучше массивы не пытаться укладывать в структуры, ибо их размер должен быть определен.
Не обязательно. Для IP стека как раз наоборот очень удобно использовать структуры с open array.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 1 2007, 17:17
Сообщение #10


Гуру
******

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



Цитата(rezident @ Jun 1 2007, 18:28) *
ИМХО, забейте на эту структуру! wink.gif

Совершенно неразумный совет.
Цитата
И интерпретируйте его первый элемент (Data[0]) как валидный размер текущего массива.

Ну зачем, о Господи! Если совершенно естественно именуется поле структуры а уж его "интерпретацией" должен заниматься компилятор. Зачем забивать себе и другим лишними знаниями, соглашениями и потенциальными ошибками.

Цитата(_Артём_ @ Jun 1 2007, 19:49) *
Пожалуй остановлюсь на массиве.

И, простите, как, это поможет проблеме???
Внимательно читайте пост defunct - Ваш вариант это динамическое выделение памяти.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jun 1 2007, 17:50
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 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)){
.....
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 1 2007, 18:20
Сообщение #12


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
rezident
сообщение Jun 1 2007, 18:43
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(zltigo @ Jun 1 2007, 23:17) *
Совершенно неразумный совет.

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

Собственно я об этом же, только без обращения к Творцу smile.gif Только зачем она в приведенном автором топика примере?
Цитата(zltigo @ Jun 1 2007, 23:17) *
Зачем забивать себе и другим лишними знаниями, соглашениями и потенциальными ошибками.

Тогда нужно на Паскале писать, а не на Си. Делов-то!
Цитата(zltigo @ Jun 1 2007, 23:17) *
Внимательно читайте пост defunct - Ваш вариант это динамическое выделение памяти.

Читайте пост Сергея Борщ о том, какие проблемы бывают с незавершенными массивами.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 1 2007, 19:00
Сообщение #14


Гуру
******

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



Цитата(rezident @ Jun 1 2007, 21:43) *
Структура это всего лишь абстракция, предназначенная для удобства человека.

Да! И зачем советовать делать не удобно???


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
defunct
сообщение Jun 1 2007, 21:24
Сообщение #15


кекс
******

Группа: Свой
Сообщений: 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) *
Вот только с выделением облом - автор хотел эти структуры во флеше хранить.


Во флеш можно хранить в удобном и нормальном для этого виде, также как у автора ветки - структуры фиксированной длинны. Экономия на мой взгляд может потребоваться во второй части задачи -
"загружаться в ОЗУ соответственно ситуации."
Вот тут как раз сэкономить поможет способ с дин. выделением памяти.
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 17:22
Рейтинг@Mail.ru


Страница сгенерированна за 0.01489 секунд с 7
ELECTRONIX ©2004-2016