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

 
 
5 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Можно ли в typedef struct описать массив переменной длины, IAR, C, AVR
west329_
сообщение Feb 20 2009, 09:52
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Есть некий протокол который пытаюсь описать структурой типа

Код
typedef struct TMainS
  {
    unsigned char   Start;
    unsigned long   Adata;
    unsigned int      Bdata;
    unsigned char   Cdata[var];
    unsigned int      Ddata;
    unsigned int      Edata;

  } T_MainS_Header;


Подскажите как в таких случаях поступат если, Cdata имеет переменную длину.

Перед присваиваем типов можно легко найти значение var.
Интересует доступ к полям Ddata и Edata, после присваивания типа MainS->Ddata или MainS->Edata.

Возможно ли такое решение, в книге по С такого ненашол, компилятор упорно ругается на Cdata, говорит что надо константа для var, и я с ним согласен, но есть ли другие решения ?

Сообщение отредактировал west329_ - Feb 20 2009, 09:57
Go to the top of the page
 
+Quote Post
ARV
сообщение Feb 20 2009, 09:58
Сообщение #2


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Cdata делайте указателем, не забывая выделять память под вашу "переменную" длину и освобождать, когда станет не нужно... либо переместите массив в конец структуры и объявите его Cdata[] - т.е. без явного указания длины...


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Feb 20 2009, 10:04
Сообщение #3


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(west329_ @ Feb 20 2009, 13:52) *
Подскажите как в таких случаях поступат если, Cdata имеет переменную длину.


Стандартами языка С С89 и С99 массивы переменной длины не предусмотрены. 2 варианта для тебя навскидку:
1. Объвить Cdata фиксированного размера, заведомо большим, чем может быть по протоколу.
2. Объвить поле unsigned char *Cdata, а затем, когда var будет известно - динамически выделять/освобождать через malloc/free.
Причина редактирования: Удаление излишнего цитирования.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 20 2009, 11:01
Сообщение #4


Гуру
******

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



Цитата(west329_ @ Feb 20 2009, 11:52) *
Подскажите как в таких случаях поступат если, Cdata имеет переменную длину.
В С массив неизвестной длины (фактически - нулевой) может располагаться только в конце структуры. В плюсах массивы переменной длины средствами языка невозможны. На С вы можете разбить вашу структуру на две - Header и Footer. В первой Start, Adata, Bdata, Cdata, во второй - Ddata, Edata. К Footer обращаетесь через указатель, который ставите на нужное место памяти, когда уже знаете значение var. При передаче можно разбить процедуру на три части - передача заголовка, передача Cdata, передача заключительной части.


--------------------
На любой вопрос даю любой ответ
"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
west329_
сообщение Feb 20 2009, 11:54
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Благодар за подсказку.
Понятно как действовать дальше, впринципе изначально планировал разбить на 2 части, но засомневался, так как опыта маловато.
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 20 2009, 14:06
Сообщение #6


Гуру
******

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



Цитата(Сергей Борщ @ Feb 20 2009, 16:01) *
В С массив неизвестной длины (фактически - нулевой) может располагаться только в конце структуры.
Дополню слова Сергея.
В таком случае (объявление без явного указания размера) массив будет incompete array, а в структуре под него будет выделена лишь переменная под указатель. Так что, если вы попытаетесь определить размер такой структуры с помощью sizeof, то результат может отличаться от ожидаемого. Это следует помнить и учитывать заранее.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 20 2009, 19:12
Сообщение #7


Гуру
******

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



Цитата(rezident @ Feb 20 2009, 16:06) *
а в структуре под него будет выделена лишь переменная под указатель.
Нет. Не будет там указателя. Размер структуры будет равен размеру без массива. При обращении к массиву будет обращение в адреса сразу за структурой. Это можно представить, как будто в структуре последним идет массив int Array[0]; а обращение идет как бы за границы этого массива.


--------------------
На любой вопрос даю любой ответ
"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
Rst7
сообщение Feb 20 2009, 19:32
Сообщение #8


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Чисто с прагматической точки зрения я бы положил в конце структуры массив с длинной, соответствующей максимально возможной. Меньше способов наступить на грабли. Сугубо ИМХО.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
west329_
сообщение Feb 21 2009, 08:25
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 378
Регистрация: 10-09-07
Из: UKR/Voz
Пользователь №: 30 423



Если забирать данные с Cdata через указатель, какой размерности должен быть указатель ?.

Предпологаю, что INT, но не утверждаю, исхожу из того, что массив имеет размерность до 400 байт, и если забирать вручную через инкремент в переменную, указатель будет возвращать по 1 байту масива или по 2 ?.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 21 2009, 10:01
Сообщение #10


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(west329_ @ Feb 21 2009, 11:25) *
Если забирать данные с Cdata через указатель, какой размерности должен быть указатель ?.
Вопрос неверен в корне.
В Вашем случае указатель имеет размерность 2 байта в любом случае, т.к. размер ОЗУ врядли более 64КБ.
Тип указателя определяется типом данных на которые он ссылается и всё. Более нет никаких характеристик у указателей.
Если он указывает на байты, то unsigned char*, если на слова то unsigned short*
Если на константные данные ссылается: const unsigned char*.
Если сам указатель должен быть константным: unsigned char* const
Если указатель константный и ссылается на сонстанту: const unsigned char* const
Ну и ещё надо не забывать о volatile, если Ваш указатель ссылается на аппаратный регистр контроллера или область памяти, которая может использоваться (изменяться) в прерываниях то надо писать так: volatile unsigned char* p = &PIND;


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Feb 21 2009, 16:59
Сообщение #11


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(west329_ @ Feb 21 2009, 12:25) *
Если забирать данные с Cdata через указатель, какой размерности должен быть указатель ?.

Предпологаю, что INT, но не утверждаю, исхожу из того, что массив имеет размерность до 400 байт, и если забирать вручную через инкремент в переменную, указатель будет возвращать по 1 байту масива или по 2 ?.


Указатель должен быть такого размера, чтобы однозначно адресовать память и зависит от процессора.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 21 2009, 17:35
Сообщение #12


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(sergeeff @ Feb 21 2009, 19:59) *
Указатель должен быть такого размера, чтобы однозначно адресовать память и зависит от процессора.
По стандарту на язык СИ "размерность" указателя равна "размерности" типа int для данной архитектуры. Если я ничего не напутал.
Для 8 и наверное для 16 битного контроллера int = short = 2 байта.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Rst7
сообщение Feb 21 2009, 17:57
Сообщение #13


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
По стандарту на язык СИ "размерность" указателя равна "размерности" типа int для данной архитектуры. Если я ничего не напутал.


Да, такое заблуждение было. До появления 64хбитных архитектур. Там int - 32 бита, указатель 64. Соответственно, size_t (разность между двумя указателями) не int, а long long.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 22 2009, 06:52
Сообщение #14


Гуру
******

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



Цитата(Rst7 @ Feb 21 2009, 20:57) *
До появления 64хбитных архитектур....

Да и "до" указетели совершенно разной размерности в пределах одной платфрмы обыденное явление - в том-же реалмоде x86 самые разнообразные по размеру, и даже два варианта 32bit, один из которых реально вовсе и не 32bit smile.gif.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Rst7
сообщение Feb 22 2009, 07:26
Сообщение #15


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
в том-же реалмоде x86


Ну да. Правда, самый мелкий указатель (в пределах сегмента) все-же соответствовал int'у. Но вообще, про платформы с сегментацией надо забывать, как о страшном сне smile.gif


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post

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

 


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


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