Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Поместить константу float на место int32
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
SasaVitebsk
Есть структура. Вся структура константная (размещается во флэши). В ней есть 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                                    // "мм"
};
adnega
Цитата(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,
};
SasaVitebsk
Спасибо. Подумал про 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 заполнять?
_pv
есть еще дурацкий вариант сконвертировать float в int руками:
http://www.h-schmidt.net/FloatConverter/
5e3 == 0x459c4000
и еще более дурацкий - сделать такой ковертер на препроцессоре sm.gif.

по поводу инициализации uniona в IARе: приведение руками к нужному типу вроде должно работать
(int) 0x4444,
(float) 5e-3

постфикс L после константы вроде только на длину указывает, а не на тип.
ну то есть
5000L - long int,
5000.0L - double
adnega
Цитата(SasaVitebsk @ Jun 24 2013, 12:30) *
Как ему указать что из union заполнять?

Не уверен, но кажется это фича gcc, а не языка C.
SasaVitebsk
Цитата(_pv @ Jun 24 2013, 11:43) *
есть еще дурацкий вариант сконвертировать float в int руками

rolleyes.gif
Так я так и делал. )) Но хочется, чтобы кто-нибудь потом разобрался ... )) У меня много таких данных. Это менюшка крупного прибора.

Приведение сейчас попробую
XVR
Цитата(_pv @ Jun 24 2013, 12:43) *
по поводу инициализации uniona в IARе: приведение руками к нужному типу вроде должно работать
(int) 0x4444,
(float) 5e-3
Не поможет. int и float легко преобразуются друг в друга С приведением типа. Причем преобразуются правильно - т.е. из целого он сделает плавающее, и наоборот. Т.е. побитовое представление изменится.

Что бы оно не менялось, нужно преобразовывать через указатели: как то так - *(int32_t*)(float*)&<ваша константа>. Но для констант это пройти не должно sad.gif

Если у вас есть C++ то вас спасет reinterpret_cast<int32_t>(5e-3f) (не забудьте про суффикс f в константе - без него это будет double, и reinterpret_cast не сработает)

_pv
Цитата(XVR @ Jun 24 2013, 16:33) *
Не поможет. int и float легко преобразуются друг в друга С приведением типа. Причем преобразуются правильно - т.е. из целого он сделает плавающее, и наоборот. Т.е. побитовое представление изменится.

это понятно, вопрос был про инициализацию uniona и там вроде как именно по типу должно определяться какое именно поле инициализируется.
SasaVitebsk
В 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};
XVR
Цитата(_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

SasaVitebsk
2 XVR. beer.gif
Проверил - работает. biggrin.gif
Правда только для union можно указать.
a14.gif
Fujitser
Однозначно только union.
Для доступа к полям union можно применять конструкции вида:
struct { int x, y, z; } point = { .y=10, .z=20, .x=30 };

(стандарт с99, в c++ работать не будет).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.