#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
, вероятно, не может быть НИКАКОГО целочисленного значения; вероятно, у него есть набор допустимых значений для проверки.