Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

pokk писал(а):в С как нибудь можно в цикле по полям структуры пройтись?
нельзя
pokk писал(а):// Вот это как сделать по феншую ?
вот так и делать

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

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

pokk:
Если все поля одного типа, как у Вас в примере, можно для такого дела завести:

Код: Выделить всё

typedef union {
  struct {
    uint8_t error1;
    uint8_t error2;
    uint8_t error3;
    uint8_t error4;
  };
  uint8_t error[4];
} Type_error;
...
Type_error te;
for (uint8_t i = 0; i < sizeof(Type_error); i++) {
  te.error[i] = 3;
}
Тогда можно и по полям обращаться, как раньше, и по индексам массива.

В принципе, можно и как в оригинале было, без union:

Код: Выделить всё

struct {
  uint8_t error1;
  uint8_t error2;
  uint8_t error3;
  uint8_t error4;
} Type_error ;
...
Type_error te;
for (uint8_t i = 0; i < sizeof(Type_error); i++) {
  *(uint8_t*)(&te + i) = 3;
}
, но это, опять же, только если все элементы структуры одного размера.
Контактная информация:
Реклама
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

WiseLord:
О за вариант с union спасибо, я примерно так же работал с массивом, только приходилось define элементы обзывать что бы не запутаться, а теперь как-то это надоело.
А про вариант, без union я уже думал, но как-то страшно, фиг его знает как компилятор структуру упакует. И при портретировании такого когда сложности могут возникать.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

pokk писал(а):фиг его знает как компилятор структуру упакует. И при портретировании такого когда сложности могут возникать
ну и зачем вам эти грабли? ну нельзя в Си перебирать поля структуры в цикле... смиритесь. все костыли вам боком выйдут.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Сообщение arkhnchul »

на всякий случай, не касаясь собственно структур
[uquote="pokk",url="/forum/viewtopic.php?p=3240362#p3240362"]Допустим как-то так, и надо выявить какая именно авария произошла.[/uquote]
не надо так делать :dont_know: если нужно регистрировать множество различных и возможно одновременных ошибок, удобнее битовые маски

Код: Выделить всё

uint32_t errors;

typedef enum {
   ERR_FOO = (uint32_t) 0x000001,
   ERR_BAR = (uint32_t) 0x000002,
   ERR_AAAAAAAAA = (uint32_t) 0x000004,
   ERR_ZOMBIEAPOCALYPSE = (uint32_t) 0x000008
} error_event_t;

....
errors = 0;
....
errors |= ERR_FOO;
....
if(errors){
   if(errors & ERR_FOO){
      .....
   }
}
Реклама
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

arkhnchul, да я сделал похоже, но в лоб(про умножение на 2), некоторые флаги достигают трех состояний.

Код: Выделить всё

//==========================
/*
	* @Описание:	Устанавливаем статусные биты(норма,предупреждение,авария).
	* @Параметр:
	* @Возврат:		Нету
*/
void SetStatus(uint8_t data,uint32_t Var){
	MatchVall.StatusAll&=(~(3<<Var*2));		//очистить место под установку битов(стереть предыдушее значение)
	MatchVall.StatusAll|= (data<<(Var*2));
}
//==========================
/*
	* @Описание:	Функция возврашает статус запрашиваемого параметра.
	* @Параметр:
	* @Возврат:		Нету
*/
uint8_t GetStatus(uint32_t Var){
uint32_t temp;
	temp=MatchVall.StatusAll&(3<<Var*2);
	temp=temp>>(Var*2);
	return temp;
}
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

pokk писал(а):да я сделал похоже, но в лоб
как с моей точки зрения, так вы сделали плохо, я бы даже сказал недопустимо, если бы мне не было все равно :))) кто вам помешал сделать нормально?

Код: Выделить всё

typedef enum{
   STATUS_OK,
   STATUS_FAIL,
   STATUS_ALARM
}status_t;
и затем в структуре объявить поле этого типа, в функциях сравнивать значение этого поля с константами, задавать константами его значение и т.п.? ну то есть как обычно все делают?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

ARV, имеете ввиду как-то так ?Да выглядит красивее, но мне дальше надо было проверять, какой либо из параметров в аварии, и не охото было условий 6-7 ставить.

Код: Выделить всё

typedef enum{
   STATUS_OK,
   STATUS_FAIL,
   STATUS_ALARM
}status_t;

typedef struct{
	status_t T;
	status_t AC;
	status_t Erorr3;
	status_t Erorr4;
}T_error_t;
T_error_t Error;

void SetStatus123(status_t data,status_t Var){
	if(data==STATUS_OK){Var=STATUS_OK;}
	if(data==STATUS_FAIL){Var=STATUS_OK;}
	if(data==STATUS_ALARM){Var=STATUS_OK;}
}

SetStatus123(STATUS_ALARM,Error.AC);
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Код: Выделить всё

void SetStatus123(status_t data,status_t Var){
   if(data==STATUS_OK){Var=STATUS_OK;}
   if(data==STATUS_FAIL){Var=STATUS_OK;}
   if(data==STATUS_ALARM){Var=STATUS_OK;}
}
это вот что должно означать? на месте компилятора я бы эту функцию выкинул, как бессмыленно-бесполезную. для обработки состояния лично я бы написал так:

Код: Выделить всё

status_t status;
...
switch(status){
case STATUS_OK:
   ...
   break;
case STATUS_FAIL:
   ...
   break;
case STATUS_ALARM:
   ...
   break;
}
как обычно все и делают...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

Ну да, я обычно так и делаю все на case, это я так в блокноте накидал для примера, но в любом случае, кучу проверок дальше это не отменяет, что бы перепроверить все эти переменные, для зажигании лампочки авария.
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Сообщение arkhnchul »

[uquote="ARV",url="/forum/viewtopic.php?p=3241502#p3241502"]как обычно все и делают[/uquote]
для единичных статусов да, а для множественных - таки обычно маски.
Zat
Встал на лапы
Аватара пользователя
Сообщения: 119
Зарегистрирован: Пн ноя 02, 2009 05:27:41
Откуда: С-Пб

Сообщение Zat »

[uquote="pokk",url="/forum/viewtopic.php?p=3240450#p3240450"]WiseLord:
О за вариант с union спасибо, я примерно так же работал с массивом, только приходилось define элементы обзывать что бы не запутаться, а теперь как-то это надоело.
А про вариант, без union я уже думал, но как-то страшно, фиг его знает как компилятор структуру упакует. И при портретировании такого когда сложности могут возникать.[/uquote]
Не знаю, берет ли компилятор, но можно ему задать выравнивание перед объявлением структуры:

Код: Выделить всё

#pragma pack(push, 1)
  struct {
    uint8_t error1;
    uint8_t error2;
    uint8_t error3;
    uint8_t error4;
  };
#pragma pack(pop)
Если GCC, то можно попробовать так:

Код: Выделить всё

  struct {
    uint8_t error1;
    uint8_t error2;
    uint8_t error3;
    uint8_t error4;
  } __attribute__ ((__packed__));
И дальше, зная что каждое поле занимает 1 байт обращаемся как к массиву. Даже если будут разные типы, мы же знаем их
размер, но будет чуть сложнее.
Грызет канифоль
Сообщения: 291
Зарегистрирован: Чт ноя 06, 2014 13:09:06

Сообщение viiv »

[uquote="Zat",url="/forum/viewtopic.php?p=3241741#p3241741"]]
И дальше, зная что каждое поле занимает 1 байт обращаемся как к массиву. Даже если будут разные типы, мы же знаем их
размер, но будет чуть сложнее.[/uquote]
не надо так делать. __packed__ и прочее для случаев, когда без них не обойтись (например, для заголовкой сетевых пакетов).
У автора вопроса явно не этот случай.


Не надо никаких union-ов. Зачем запутывать? Если четыре поля ошибок нормально (я не телепат), то

Код: Выделить всё

typedef struct{
   uint8_t error1;
   uint8_t error2;
   uint8_t error3;
   uint8_t error4;
};

void err_copy_123 (Type_error *dst, Type_error *src)
{
    dst->error1 = src->error1;
    dst->error2 = src->error2;
    dst->error3 = src->error3;
}
Просто, понятно, переносимо, будет работать, как и задуманно (копировать три нужных поля) если в структуру добавить еще полей (и не важно в каком порядке) и даже, если в будущем поле увеличится (например, uint16_t error2;). А если еще и имена полей и функций будут отражать суть - по мне, так вообще будет хорошо.
Чем не устраивает?
Друг Кота
Аватара пользователя
Сообщения: 7382
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Мммм, у меня затык в вроде бы простом месте. Препроцессор. Есть макрос COMMAPOS, который я могу назвать LEFT, RIGHT или не назвать совсем.
Так вот, если я этот макрос не определяю, то почему-то компилируется условие #if, а не #else:

Код: Выделить всё

#if COMMAPOS == LEFT
#warning Left
#else
#warning Not LEFT
#endif

#if COMMAPOS == RIGHT                    
#warning Right
#else
#warning Not right
#endif
Так что если макрос не определён, я получаю:
main.c:498: warning: (162) #warning: Left
main.c:505: warning: (162) #warning: Right
Хотя ожидал получить в обоих случаях "not".

Что я не понимаю?

Чёрт, да ему до фонаря на значение этого макроса!
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Сообщение arkhnchul »

в условияй макросов нельзя сравнивать со строками. Определите макросы LEFT и RIGHT как числа или символы, тогда прокатит
Друг Кота
Аватара пользователя
Сообщения: 7382
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

В гугле нашел такой пример: http://www.c-cpp.ru/books/if-else-elif-i-endif
Например, следующий фрагмент использует значение ACTIVE_COUNTRY для определения де­нежного знака:

Код: Выделить всё

 #define US 0
 #define ENGLAND 1
 #define FRANCE 2
 #define ACTIVE_COUNTRY US
 #if ACTIVE_COUNTRY==US
 char currency[] = "dollar";
 #elif ACTIVE_COUNTRY==ENGLAND
 char currency[] = "pound";
 #else
 char currency[] = "franc";
 #endif
С цифрами, конечно, работает.

Хм. вот еще нагуглил: •Expressions must have integral type and can include only integer constants, character constants, and the defined operator
Как понять character constant? это один символ?

Добавлено after 39 minutes 10 seconds:
Ага. Этот фокус работает:
#define COMMAPOS 'L'
#if COMMAPOS == 'L'
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

[uquote="uldemir",url="/forum/viewtopic.php?p=3244433#p3244433"]Есть макрос COMMAPOS, который я могу назвать LEFT, RIGHT или не назвать совсем.[/uquote]
Так определяете?

Код: Выделить всё

#define COMMAPOS LEFT
А LEFT во что определён? Если ни во что - то ваш #if сравнивает ничто с ничем. А они равны. :-D
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

Сообщение arkhnchul »

[uquote="Siarzhuk",url="/forum/viewtopic.php?p=3244521#p3244521"]А LEFT во что определён? Если ни во что - то ваш #if сравнивает ничто с ничем. А они равны. :-D[/uquote]
емнип поведение в #if при сравнении с идентификатором, не определенным как макрос, в стандарте не описано и дано на откуп компилятору. GCC, к примеру, приводит их к числовому нулю
expression is a C expression of integer type, subject to stringent restrictions. It may contain:
...
- Identifiers that are not macros, which are all considered to be the number zero. This allows you to write #if MACRO instead of #ifdef MACRO, if you know that MACRO, when defined, will always have a nonzero value. Function-like macros used without their function call parentheses are also treated as zero.
Zat
Встал на лапы
Аватара пользователя
Сообщения: 119
Зарегистрирован: Пн ноя 02, 2009 05:27:41
Откуда: С-Пб

Сообщение Zat »

[uquote="pokk",url="/forum/viewtopic.php?p=3240362#p3240362"]Добрый день подскажите в С как нибудь можно в цикле по полям структуры пройтись? и проверить их скажем на больше меньше числа. А в C ++ ?

Допустим как-то так, и надо выявить какая именно авария произошла.

Код: Выделить всё

typedef struct{
	uint8_t error1;
	uint8_t error2;
	uint8_t error3;
	uint8_t error4;
}Type_error;
Или перекопировать из одной переменной Type_error в другую с таким же типом , только несколько полей скажем все кроме одного.

Код: Выделить всё

Type_error  Err1;
Type_error  Err2;
Err1.error1=Err2.error1;  // Вот это как сделать по феншую ?
Err1.error2=Err2.error2;
Err1.error3=Err2.error3;
[/uquote]

А обязательно структура нужна ? Если бы это был постоянный ввод с неизвестным размером данных, это одно. Но тут же все
в пределах размера стека. Можно и без структуры обойтись.

Код: Выделить всё

uint8_t  Err1[4] ={0};
uint8_t  Err1[4] ={0};
Err1[0]=Err2[0];
Err1[1]=Err2[1];
Err1[2]=Err2[2];

//сравниваем
if (Err1[0] < 2) return false;
else if (Err1[0] == 4) return false;
else if (Err1[0] > 8) return true;

//Или как показывали раньше, через switch
Можно и по маске сравнивать и весь массив обежать при желании.
Друг Кота
Аватара пользователя
Сообщения: 7382
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

[uquote="Siarzhuk",url="/forum/viewtopic.php?p=3244521#p3244521"]А LEFT во что определён? Если ни во что - то ваш #if сравнивает ничто с ничем. А они равны. :-D[/uquote]Ага, тогда если бы я перед этим определил

Код: Выделить всё

#define LEFT 1
#define RIGHT 2
то это заработало бы?
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Ответить

Вернуться в «Разные вопросы по МК»