Можно ли просматривать структуру?

#c #structure

#c #структура

Вопрос:

Мне нужно заполнять структуру каждые 10 мС, в этой структуре есть 230 переменных, только bool и int . Сначала я подумал о том, чтобы заполнить и инициализировать случайным образом одну за другой все переменные. Но это очень долго писать и кажется очень уродливым кодом. Также эта структура часто меняется.

Итак, моей второй мыслью было просмотреть структуру (возможно, с помощью цикла? ) и заполнить случайным образом каждую переменную.

После некоторых исследований я ничего не могу найти. Итак, есть ли способ просмотреть мою структуру и заполнить переменную случайным образом?

Спасибо за вашу помощь.

РЕДАКТИРОВАТЬ: вот что я пытаюсь сделать :

У меня есть заголовочный файл, содержащий структуру :

     typedef struct
        {
            /// Statut Ground-Flight
            int _statutGroundFlight;
            /// Statut Capteur de presence
            bool _statutCapteurPrensence;
            /// Statut Bouton OPEN in
            bool _statutBoutonOpenIn;
            /// Statut Bouton OPEN ext
            bool _statutBoutonOpenExt;
            /// Statut Bouton CLOSE in
            bool _statutBoutonCloseIn;
            /// Statut Bouton CLOSE ext
            bool _statutBoutonCloseExt;
...
  

И вот что я хочу делать каждые 10 мС:

 //Create a structure
struct myStruct;

//Browse the structure
for(int i; myStruct.size();   i){
   if(myStruct[i] is int){
      //Fill it randomly with int
   }
   if(mystruct[i] is bool){
      //Fill it randomly with bool
   }
}
  

Комментарии:

1. Вы хотите инициализировать структуру? Из вашего вопроса неясно, что вы хотите сделать.

2. Заполнять случайным образом? По умолчанию c не инициализирует переменные, что означает, что w / e was остается в памяти, остается там (это в значительной степени случайно).

3. Почему не использовать std::map для хранения данных структуры? Вам было бы легче выполнять итерации по каждому элементу.

4. @atoMerz: Это ужасный комментарий. Чтение неинициализированного значения имеет неопределенное поведение!

5. @EvansBelloeil: Я думаю, вы просите о каком-то размышлении , но не о хорошем. Над размышлениями ведется работа, но я сомневаюсь, что это хороший способ решить вашу проблему. Вероятно, у вас не должно быть структуры с более чем 100 объявлениями членов… У вас случайно нет таких членов, как enemy1 , enemy2 , …, enemy15 /* TODO: support more enemies */ , weapon1, weapon2`…?

Ответ №1:

Я не думаю, что есть способ просматривать структуру и заполнять переменные так, как вы хотите, но вы можете избежать написания кодов с помощью макроса. Вы можете написать макрос и позволить препроцессору сгенерировать код для вас .. например:

создайте один struct.def, где вы можете определить обязательные поля

 #ifndef INTEGER
#error "INTEGER not defined"
#endif
#ifndef BOOL
#error "BOOL not defined"
#endif  
#ifndef create_struct 
#error "create_struct not defined"
#endif  


create_struct(my_struct,
        INTEGER(i1)
        BOOL(b1,false)
        INTEGER(i2)
        INTEGER(i3)
        BOOL(b2,true)
        BOOL(b3,false)
        BOOL(b4,false)
        INTEGER(i4)
        //add or modify fields here
)       

#undef INTEGER
#undef BOOL
#undef create_struct
  

Затем напишите макрос в своем коде, используя приведенный выше файл

 #include "stdio.h"
#include "string.h"
//create structure
#define INTEGER(var_name) int var_name;
#define BOOL(var_name,data) bool var_name;
#define create_struct(struct_id,data_type)
        typedef struct struct_id##_tag{
                data_type
        }struct_id;
#include "struct.def"
//-------------------------------------------

//function to initialize default value
#define INTEGER(var_name) p->var_name=0;
#define BOOL(var_name,data) p->var_name=data;
#define create_struct(struct_id,data_type)
        void initialize_##struct_id(struct_id* p)
        {
                data_type
        }
#include "struct.def"
//-------------------------------------------------

//function to fill random value to structure        
#define INTEGER(var_name) p->var_name=rand();
#define BOOL(var_name,data) p->var_name=rand()%2;
#define create_struct(struct_id,data_type)
        void fill_random_##struct_id(struct_id* p)
        {
                data_type
        }
#include "struct.def"
//-----------------------------------------
  

Теперь, если вы запустите препроцессор, он сгенерирует для вас приведенный ниже код….

 typedef struct my_struct_tag{
        int i1;
        bool b1; 
        int i2; 
        int i3;
        bool b2; 
        bool b3; 
        bool b4; 
        int i4; 
}my_struct;
void initialize_my_struct(my_struct* p) { 
        p->i1=0; 
        p->b1=false; 
        p->i2=0;
        p->i3=0; 
        p->b2=true;
        p->b3=false; 
        p->b4=false;
        p->i4=0; 
}
void fill_random_my_struct(my_struct* p) {
        p->i1=rand(); 
        p->b1=rand()%2;
        p->i2=rand(); 
        p->i3=rand(); 
        p->b2=rand()%2;
        p->b3=rand()%2;
        p->b4=rand()%2; 
        p->i4=rand();
}
  

Теперь, если вы хотите изменить свою структуру, вам нужно изменить только в одном месте, которое находится в struct.def файле

Вы можете проверить ссылку http://rajenpandit.blogspot.in/p/using-macro.html для получения более подробной информации.

Ответ №2:

Я бы предпочел использовать std::map для хранения значений ваших членов.

 class MyStructure
{
    std::map< unsigned int, int > integerValues;
    std::map< unsigned int, bool > booleanValues;
public:
    bool amp; exampleBoolean = booleanValues[ 0 ];
    int amp; exampleInteger = integerValues[ 0 ];
    void randomIntegers() { 
        for( auto amp; integer : integerValues )
            integer.second = randomInteger(); // put your favorite random here
    }
};
  

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

Я бы рекомендовал использовать enum имена полей для индексации карты.

Ответ №3:

Простой подход заключается в группировании полей одного типа, а затем создании объединения с массивами, зависящими от типа.

Пример в ideone.com

 #include <iostream>
using namespace std;

union X
{
    struct
    {
        int i1, i2, i3;
        bool b1, b2, b3;
    };

    struct
    {
        int is[3];
        bool bs[3];
    };
};

std::ostreamamp; operator<<(std::ostreamamp; os, const Xamp; x)
{
    os << "{ ";
    for (int i = 0; i < 3;   i)
        os << x.is[i] << ' ' << x.bs[i] << ' ';
    return os << '}';
}

int main()
 {
    for (int i = 0; i < 3;   i)
    {
        X x;
        for (int j = 0; j < 3;   j)
        {
            x.is[j] = rand();
            x.bs[j] = rand() % 2;
        }
        std::cout << x << 'n';
    }
}
  

(Конечно, вы должны сделать что-то лучше, чем жестко кодировать размеры массива везде, где он индексируется, и позволять количеству int s и bool s меняться независимо, но это все тривиально ….)

Пример вывода:

 { 1804289383 0 1681692777 1 1957747793 1 }
{ 719885386 0 596516649 1 1025202362 1 }
{ 783368690 1 2044897763 0 1365180540 0 }
  

Ответ №4:

Вы не можете перебирать поля структуры, как вы хотите.

Если это для теста, то вам не следует адаптировать структуру в соответствии с тестом. Вместо этого просто сделайте это «жестким» способом — заполните каждое поле. Это также важно, потому что разные поля, безусловно, имеют разные способы быть «случайными». Например _statutGroundFlight , вероятно, не может быть НИКАКОГО целочисленного значения; вероятно, у него есть набор допустимых значений для проверки.