Easyelectronics.ru

Электроника для всех
Текущее время: 16 окт 2018, 08:58

Часовой пояс: UTC + 5 часов



    • JLCPCB - Прототипы 10 PCBs всего за 2$ (100*100mm, 2-layer)
    • Как мы делаем платы, смотрите на YouTube
    • Крупнейшая китайская фабрика прототипов. 300000+ заказчиков и 10000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин комплектующих.

Начать новую тему Ответить на тему  [ Сообщений: 20 ] 
Автор Сообщение
 Заголовок сообщения: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 21 мар 2016, 18:01 
Старожил

Зарегистрирован: 24 июн 2011, 14:05
Сообщения: 287
Откуда: Новочеркасск
Задался тут вопросом (от лени конечно), есть вот такая структура например (на самом деле у меня структура больше 100 флагов):
Код:
struct{
    uint16 flag_1:1;
    uint16 flag_2:1;
    uint16 flag_3:1;
    uint16 flag_4:1;
    uint16 flag_5:1;
    uint16 flag_6:1;
    uint16 res:10;
}koni;

Флаги в структуре могу взводиться в любой последовательности, но какой-то из этих флагов будет взведён первым. Узнать какой из флагов взвёлся первым или взвёлся в данный момент не проблема (потому как взводит их сама программа и в месте взвода можно определить номер флага), но номер флага как определить? (щас определяется в лоб: пишу номер взведённого флага в том месте где он и взводиться, но если где-то в начале или середине добавились флаги то нужно всё пересчитывать).
Можно сделать через кучу define, но тоже много ручной работы.
Есть ли какие нибудь операторы типа sizeof(), которые могут это делать.

Забыл еще: физически память 16-ти битная, и обращение по адресам к ней только 16-ти битное.


Последний раз редактировалось ELEKTROS 21 мар 2016, 19:17, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 21 мар 2016, 18:44 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2524
Откуда: Санкт-Петербург
Навскидку - старый трюк с препроцессором:
Код:
#define LIST \
  F(1) \
  F(2) \
  ... \
  F(100)

#define F(x) uint16 flag_##x:1;
struct{
  LIST
  uint16 res:10;
}koni;
#undef F

#define F(x) number_##x,
enum {
  LIST
}
#undef F

#define F(x) koni.flag_##x=1; num = number##x;
ну и так далее

Хотя если у флагов только номера, а не произвольные имена - то можно обойтись только последней строчкой.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 21 мар 2016, 19:02 
Старожил

Зарегистрирован: 24 июн 2011, 14:05
Сообщения: 287
Откуда: Новочеркасск
У флагов конечно произвольные имена в общем случае, это так для наглядности написал.

Не канает с первого взгляда. Нужно знать номера флагов при их установке, потому как в последнем дефайне F(x), х-номер флага, так зачем вообще вся бодяга выше?


Последний раз редактировалось ELEKTROS 21 мар 2016, 19:27, всего редактировалось 3 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 21 мар 2016, 19:11 
Старожил

Зарегистрирован: 10 окт 2014, 00:48
Сообщения: 4967
(Смещение элемента от начала структуры)/2 = разве не есть ее номер?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 21 мар 2016, 19:16 
Старожил

Зарегистрирован: 24 июн 2011, 14:05
Сообщения: 287
Откуда: Новочеркасск
u37, как это будет выглядеть?
У меня же получается первые 16 элементов лежат по одному адресу, вторые 16 элементов по второму адресу и так далее.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 21 мар 2016, 19:35 
Старожил

Зарегистрирован: 10 окт 2014, 00:48
Сообщения: 4967
1. стало ^ было = новое.
2. в "новое" выискивать номер бита !=0.

Самый простой вариант - отказаться от битовых операций и перейти к байтовым. Битовые операции априори не атомарны, а потому возможны искажения данных.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 21 мар 2016, 19:40 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2524
Откуда: Санкт-Петербург
u37, в его случае смещение не вычислить (битовые поля).

ELEKTROS, трюк-то поняли? Ну, как по одному списку имён сгенерить и тип структуры, и enum с номерами полей, и ещё что-нибудь (например, список обработчиков команд)?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 21 мар 2016, 19:42 
Старожил

Зарегистрирован: 24 июн 2011, 14:05
Сообщения: 287
Откуда: Новочеркасск
aamonster, видимо задолбался, щас только потихоньку доходит как сделать с разными именами. :)
u37, у меня переходить нужно не на байтовые, а на операции со словами (причину читайте выше). А это в 16-ть раз больше памяти.
Вот немного изменил, куча предупреждений (потом их выпилить попробую), но компилиться.
Еще без перечислений вообще, придумать осталось.
Код:
#define LIST \
  F(error_hard_termo_rele) \
  F(error_hard_drive_switch_up_gen) \
  F(error_hard_switch_up_acb) \
  F(error_hard_switch_down) \
  F(error_hard_cur_excit_gen) \
  F(error_hard_overload_tmp2) \
  F(error_hard_cur_excit_acb) \
  F(error_hard_break_tmp2) \
  F(error_hard_overload_udc1) \
  F(error_hard_overload_udc2) \
  F(error_24_invert1) \
  F(error_24_invert2) \
  F(error_end_switch_invert1) \
  F(error_end_switch_invert2) \
  F(error_end_switch_gen) \
  F(error_soft_tmp_isol1)

#define F(x) Uint16 XCONCAT(x, ):1;
struct KONI_STR{
  LIST
}koni;
#undef F

#define F(x) XCONCAT(number,x),
enum {
  zero,
  LIST
}num;
#undef F
union{
   Uint16 all;
   struct KONI_STR bit;
}uniont;
#define F(x) XCONCAT(uniont.bit.,x)=1; num = XCONCAT(number,x);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 24 мар 2016, 14:47 
Старожил

Зарегистрирован: 24 июн 2011, 14:05
Сообщения: 287
Откуда: Новочеркасск
Довёл до работоспособного варианта:

Код:
#define LIST_ERROR \
  F(hard_termo_rele) \
  F(hard_drive_switch_up_gen) \
  F(hard_switch_up_acb) \
  F(hard_switch_down) \
  F(hard_cur_excit_gen) \
  F(hard_overload_tmp2) \
  F(hard_cur_excit_acb) \
  F(hard_break_tmp2) \
  F(hard_overload_udc1) \
  F(hard_overload_udc2) \
  F(24_invert1) \
  F(24_invert2) \
  F(end_switch_invert1) \
  F(end_switch_invert2) \
  F(end_switch_gen) \
  F(soft_tmp_isol1)

#define F(x) XCONCAT(enum_,x),
typedef enum{
   ZERO,
   LIST_ERROR
   LAST
}NUMBER_ALARM_EN;
#undef F

#define F(x) Uint16 XCONCAT(er_,x):1;
typedef struct{
   LIST_ERROR
}KONI_STR;
#undef F

NUMBER_ALARM_EN num;
union ERROR_UNION{
   Uint16 all;
   KONI_STR bit;
}uniont;

#define F(x) uniont.bit.XCONCAT(er_,x)=1; num = XCONCAT(enum_,x)

F(hard_overload_udc1);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 11 янв 2018, 07:46 
Здравствуйте!

Зарегистрирован: 10 янв 2018, 17:21
Сообщения: 1
Подскажите пожалуйста.
Есть битовое поле.
struct {
unsigned char f1 : 1;
unsigned char f2 : 1;
unsigned char f3 : 1;
} flags;

Можно ли установить бит f3, такой командой
flags |= 1<< 2


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 11 янв 2018, 09:28 
Заглядывает иногда

Зарегистрирован: 15 июн 2011, 07:52
Сообщения: 90
UMV писал(а):
Можно ли установить бит f3, такой командой
flags |= 1<< 2

*((int*)&flags) |= 1<<2; // это если по-быстрому
Или можно определить оператор |= для самой структуры (это для с++).
И ещё: структура должна быть упакована! (#pragma pack.....)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 11 янв 2018, 13:20 
Старожил
Аватара пользователя

Зарегистрирован: 01 авг 2016, 10:47
Сообщения: 263
Откуда: Таганрог
можно попробовать использовать макрос offsetof.

Show


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 11 янв 2018, 14:08 
Заглядывает иногда

Зарегистрирован: 15 июн 2011, 07:52
Сообщения: 90
У него битовые поля, они через offsetoff не определятся.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 12 янв 2018, 03:51 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 487
доброго времени суток !

Создавать структуру к которой потом обращаться по индексу или по оффсету по моему глупо. У u37 было по моему правильное предложение - исключающее или между старым и новым значением. Я бы делал как то так :
Код:
uint16_t old_b[2];   // 32 бита битовое поле старое и новое для получения изменений
uint16_t new_b[2];

uint16_t (*const func_b[])()={func1,func2,func3,func4,..,func32};

void bit_bunc() {
       for (uint8_t i1 = 0; i1 < 2;i1++) {
            uint16_t wt = olb_b[i1] ^ new_b[i1];
            if (wt) for (uint8_t i2 = 0; i2 < 16; i2++)
                          if (wt & (1 << i2)) funcb[i2 + (i1*16)]();
       }
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 12 янв 2018, 08:30 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2359
А зачем, извините, к битовым полям обращаться через |= , если они и без того создавались, чтобы обращаться через flags.f2 = 1; flags.f1 = 0;
То, какие машинные инструкции будут использованы, зависит от железа и от компилятора.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 12 янв 2018, 08:48 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2524
Откуда: Санкт-Петербург
Но вообще как-то битовые поля не прижились: я навскидку и не вспомню, где в реальных исходниках используются битовые поля, а не битовые операции (а битовые операции + enum для битов - повсеместны)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 12 янв 2018, 08:53 
Заглядывает иногда

Зарегистрирован: 14 ноя 2014, 15:16
Сообщения: 49
Язык С был разработан для системного программирования, а а битовые поля отлично описывали флаги регистров внешних устройств.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 12 янв 2018, 09:56 
Старожил
Аватара пользователя

Зарегистрирован: 23 сен 2012, 20:35
Сообщения: 2376
aamonster писал(а):
Но вообще как-то битовые поля не прижились: я навскидку и не вспомню, где в реальных исходниках используются битовые поля, а не битовые операции (а битовые операции + enum для битов - повсеместны)

Насколько я понимаю, стандарт предоставляет слишком много свободы компилятору при работе с битовыми полями. Как следствие, с их помощью сложно описывать какие-либо структуры с фиксацией их бинарного представления. Битовые операции этого недостатка лишены, хотя и менее удобны.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 12 янв 2018, 17:47 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 2359
aamonster писал(а):
Но вообще как-то битовые поля не прижились: я навскидку и не вспомню, где в реальных исходниках используются битовые поля, а не битовые операции (а битовые операции + enum для битов - повсеместны)

Ну вот например в подобных примерах:
Код:
struct device_info {
    uint8_t mode :3;
    uint8_t state :2;
    uint8_t pow_ok :1;
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Определить номер элемента структуры в С или С++
СообщениеДобавлено: 12 янв 2018, 18:28 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 23 мар 2012, 16:18
Сообщения: 146
aamonster писал(а):
Но вообще как-то битовые поля не прижились: я навскидку и не вспомню, где в реальных исходниках используются битовые поля, а не битовые операции (а битовые операции + enum для битов - повсеместны)

В микроконтроллерах постоянно используются, например:

Код:
typedef union {       
  struct {           
    uint32_t ENABLE:1;
    uint32_t SINGLE:1;
    uint32_t SPEED:2;
    uint32_t :1;     
    uint32_t INTSEL:2;
    uint32_t :1;     
    uint32_t MUXNEG:3;
    uint32_t :1;     
    uint32_t MUXPOS:2;
    uint32_t :1;     
    uint32_t SWAP:1; 
    uint32_t OUT:2;   
    uint32_t :1;     
    uint32_t HYST:1; 
    uint32_t :4;     
    uint32_t FLEN:3; 
    uint32_t :5;     
  } bit;             
  uint32_t reg;       
} AC_COMPCTRL_Type;   

Удобно.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 20 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB