用随机数初始化的对象

时间:2015-03-17 03:52:20

标签: c++ random

我对c ++和oo很新,所以这可能是非常愚蠢的事情。这完全在我的include语句之后的代码中。

enum ObjType { CUBE, CONE, };
typedef struct {
   ObjType type;
   float x;
   float y;
   float z;
   int selected;
} object;

static object objects[] =
{ 
    { CUBE, rand()%11-4, rand()%-10-5, rand()%-65-55, 0},
    { CONE, rand()%11-4, rand()%-10-5, rand()%-65-55, 0},
}

我在主方法中调用srand,传入当前时间。但是,每次程序错误时,这都会产生相同的随机数。我不理解的是什么?

2 个答案:

答案 0 :(得分:5)

正如天顶所说,全局变量的初始化发生在main()之前。您可以先执行srand()运行,例如通过初始化调用srand()声明一个全局变量,然后在static object objects[]初始化之前执行:

static int x = (srand(time(NULL)), 10);

static object objects[] =
{ 
    { CUBE, rand()%11-4, rand()%-10-5, rand()%-65-55, 0},
    { CONE, rand()%11-4, rand()%-10-5, rand()%-65-55, 0},
};

但是全局变量无论如何通常都是一个坏主意,并且依赖于初始化顺序(在同一个翻译单元中初始化的对象之间只能很好地指定)这一点特别糟糕。

而只是使用局部变量:

int main() {
  srand(time(NULL));

  object objects[] =
  { 
    { CUBE, rand()%11-4, rand()%-10-5, rand()%-65-55, 0},
    { CONE, rand()%11-4, rand()%-10-5, rand()%-65-55, 0},
  };

  // pass objects around as needed
  foo(objects[0]);
  foo(objects[1]);
}

C ++标准库现在提供优于srand()rand()的工具,并手动转换结果以生成特定的分布。使用标题<random>,使用std::mt19937代替random_device创建{种子time(NULL)等生成器,并使用分发对象:

#include <random>

int main() {
  std::random_device r;
  std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
  std::mt19937 eng(seed);

  std::uniform_int_distribution<> dist;
  object objects[] =
  { 
    { CUBE, dist(eng, {-4, 6}), dist(eng, {-5, 4}), dist(eng, {-55, 9}), 0},
    { CONE, dist(eng, {-4, 6}), dist(eng, {-5, 4}), dist(eng, {-55, 9}), 0},
  };

  // pass objects around as needed
  foo(objects[0]);
  foo(objects[1]);
}

请注意这是多么容易阅读,直到说明所需的时间间隔,而不是依赖于%对负数的行为。

(我甚至不确定你的原始间隔是不是错误,但我会忠实地再现它们,假设%的共同行为有负数,这不是'#1}。甚至标准化直到C ++ 11。)

答案 1 :(得分:3)

在输入main之前,将初始化全局变量。

您的objects是一个全局变量,因为它在任何函数之外声明。

有效地,rand()会在srand()之前调用,从而产生相同的随机数。