|
|
  |
Поместить константу float на место int32, Чистый си. |
|
|
|
Jun 24 2013, 07:07
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Есть структура. Вся структура константная (размещается во флэши). В ней есть 2 поля int. Дописывал функционал. Ввёл ещё одно поле, которое определяет тип констант. И работаю с ними поразному - или как с int32 или как с float. А вот при заполнении такой структуры вываливается ошибка. Как правильно записать, чтобы компилятор понял, что я от него хочу? Код typedef const struct { const int32_t *Index; // Указатель на редактируемый параметр/ смещение для каналов const uint16_t Ch; // 0/ Указатель на канал const uint8_t fSignEn; // Отображение знака числа const uint8_t LenDig; // Число цифр в числе (0 - гашение незначащих нулей) const uint8_t DigAfterDot; // Число цифр после точки (0 - точки нет) const uint8_t DigType; // Тип результирующего числа (0 - int8, 1 - int16, 2 - int32, 3 - float) const int32_t min,max; // минимальное и максимальное значение (если <min, то min, если >max, то max) const uint16_t typeEditing; // возможножность редактирования void (*savefunc)(void); // Указатель на функцию записи редактируемых параметров const char* const* NameUnits; // наименование единиц измерения } DigEditing_t; Код //*************************************************************** // @@ 23155. Диаметр трубопровода 1 DigEditing_t dgeD12_1 = // Меню "Диаметр трубопровода" { 0, // непрямое offsetof(PipelineChanal_t,QConfChanal[0])+offsetof(QConfChanal_t,dia_D12), // 0, // неотображать знак 7, 3, // 3 знака, нет запятой (int32_t)1.0,(int32_t)5.0e3, // min,max 3, // float PRGEDIT, 0, // Редактировать по паролю, не сохранять (сохранять по выходу из PRG) &strMm // "мм" };
|
|
|
|
|
Jun 24 2013, 07:34
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(SasaVitebsk @ Jun 24 2013, 11:07)  Как правильно записать, чтобы компилятор понял, что я от него хочу? В gcc делаю так: CODE //----------------------------------------------------------------------------- // typedef struct sPARAM //----------------------------------------------------------------------------- typedef struct sPARAM { int delta; DWORD act_datetime;
BYTE park_mask; BYTE wait_on; BYTE wait_period; BYTE pre_on;
BYTE pre_period; BYTE fin_on; BYTE fin_period; BYTE to_pre;
BYTE to_fin; BYTE to_done; BYTE l_pre; BYTE l_fin;
BYTE to_btn_press; BYTE to_btn_release;
union { DWORD flags; struct { union { WORD ev_msk; struct { WORD ev_msk_total:1; WORD ev_msk_restart:1; WORD ev_msk_power_fail:1; WORD ev_msk_enter:1; WORD ev_msk_start:1; WORD ev_msk_release:1; WORD ev_msk_enable:1; WORD ev_msk_disable:1; WORD ev_msk_reserv:8; }; };
WORD btn_inv:1; WORD box_led_inv:1; WORD flags_reserv:14; }; };
} sPARAM;
//----------------------------------------------------------------------------- // const sPARAM param_default //----------------------------------------------------------------------------- const sPARAM param_default = { delta: 0, // delta act_datetime: ACT_ALWAYS,// ACT_NEVER, park_mask: 0, wait_on: RED_TIME(0.2), wait_period: RED_TIME(3.0), pre_on: RED_TIME(0.2), pre_period: RED_TIME(0.5), fin_on: RED_TIME(1.0), fin_period: RED_TIME(1.0), to_pre: TO_TIME(1.0), to_fin: TO_TIME(10.0), to_done: TO_TIME(2.0), l_pre: DISTANCE(1.0), l_fin: DISTANCE(0.4), to_btn_press: TO_BTN(1.0), to_btn_release: TO_BTN(1.0), ev_msk: 0, btn_inv: 0, box_led_inv: 0, };
|
|
|
|
|
Jun 24 2013, 08:30
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Спасибо. Подумал про union, но немноого не в том ключе. Переклинило чего-то. Как-то я вообще очень редко union применяю. Непроходит. У меня IAR. Объявил тип: Код typedef union { float f; int32_t i; } variant_t; теперь изменил строчку структуры на const variant_t min,max; // минимальное и максимальное значение (если <min, то min, если >max, то max) Работаю соответственно с min.i и min.f. Всё прекрасно (собственно как и было). При заполнении структуры IAR не даёт указать имя поля (как у Вас). И присваивает все значения как float. хотя я и ставлю L для константы например 200L Как ему указать что из union заполнять?
|
|
|
|
|
Jun 24 2013, 08:43
|
Гуру
     
Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954

|
есть еще дурацкий вариант сконвертировать float в int руками: http://www.h-schmidt.net/FloatConverter/5e3 == 0x459c4000 и еще более дурацкий - сделать такой ковертер на препроцессоре  . по поводу инициализации uniona в IARе: приведение руками к нужному типу вроде должно работать (int) 0x4444, (float) 5e-3 постфикс L после константы вроде только на длину указывает, а не на тип. ну то есть 5000L - long int, 5000.0L - double
|
|
|
|
|
Jun 24 2013, 09:33
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(_pv @ Jun 24 2013, 12:43)  по поводу инициализации uniona в IARе: приведение руками к нужному типу вроде должно работать (int) 0x4444, (float) 5e-3 Не поможет. int и float легко преобразуются друг в друга С приведением типа. Причем преобразуются правильно - т.е. из целого он сделает плавающее, и наоборот. Т.е. побитовое представление изменится. Что бы оно не менялось, нужно преобразовывать через указатели: как то так - *(int32_t*)(float*)&<ваша константа>. Но для констант это пройти не должно Если у вас есть C++ то вас спасет reinterpret_cast<int32_t>(5e-3f) (не забудьте про суффикс f в константе - без него это будет double, и reinterpret_cast не сработает)
|
|
|
|
|
Jun 24 2013, 09:40
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
В QT, кстати, те же проблемы. Тему не закрываю. Интересно кто и как с такими вопросами борется. Для С++ тоже актуально. Я свою проблему решил. Я сделал две идентичных структуры. Одну с полями int, вторую с полями float. При обработке поступаю как и прежде. А при ображении к структуре всё работает. Код //*************************************************************** // @@ 15. MenuItem_t mnuitSysClock[5] = // Меню "Настройка часов"/ Пункты меню { {&imCorrClock, // Коррекция времени @@ 151 0,MenuTimeCorr,0,MenuTimeHlp}, {&imLocalClock, // Местное время @@ 152 0,MenuTimeEdit,0,MenuTimeHlp}, {&imTimeZone, // Часовой пояс @@ 153 (struct Menu_t *)&dgeTimeZone,EditIntCh,0,TimeZoneHlp}, {&imSumWin, // Летнее/зимнее @@ 154 (struct Menu_t *)&rbtSumWin,RadioBtnCh,0,RadioBtnHlp}, {&imCorrFreq, // Коррекция генератора @@ 155 (struct Menu_t *)&dgeFreqRtcCorr,EditIntCh,0,EditIntHlp}, };
struct Menu_t mnuSysClock = // Меню "Настройка часов" {5,mnuitSysClock};
|
|
|
|
|
Jun 24 2013, 10:47
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(_pv @ Jun 24 2013, 13:39)  это понятно, вопрос был про инициализацию uniona и там вроде как именно по типу должно определяться какое именно поле инициализируется. Не должно. Стандарт С99, раздел 6.7.8 (Initialization), пункт 17,18: Цитата 17. Each brace-enclosed initializer list has an associated current object. When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union.127) In contrast, a designation causes the following initializer to begin initialization of the subobject described by the designator. Initialization then continues forward in order, beginning with the next subobject after that described by the designator.128)
18. Each designator list begins its description with the current object associated with the closest surrounding brace pair. Each item in the designator list (in order) specifies a particular member of its current object and changes the current object for the next designator (if any) to be that member.129) The current object that results at the end of the designator list is the subobject to be initialized by the following initializer. Сноски 127,128: Цитата 127) If the initializer list for a subaggregate or contained union does not begin with a left brace, its subobjects are initialized as usual, but the subaggregate or contained union does not become the current object: current objects are associated only with brace-enclosed initializer lists. 128) After a union member is initialized, the next object is not the next member of the union; instead, it is the next subobject of an object containing the union. Так что увы, тип константы полностью игнорируется. Но в том же С99 есть синтаксис инициализации с указанием конкретного поля (a-la GCC, но немного по другому) Код initializer: assignment-expression { initializer-list } { initializer-list , }
initializer-list: designationopt initializer initializer-list , designationopt initializer
designation: designator-list =
designator-list: designator designator-list designator
designator: [ constant-expression ] . identifier
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|