我对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,传入当前时间。但是,每次程序错误时,这都会产生相同的随机数。我不理解的是什么?
答案 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()
之前调用,从而产生相同的随机数。