用随机数初始化的对象
Object initialized with random numbers
我对 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,传递了当前时间。但是,每次程序出错时都会生成相同的随机数。我有什么不明白的?
全局变量将在进入main
之前初始化。
你的 objects
是一个全局变量,因为它是在任何函数之外声明的。
实际上,rand()
在 srand()
之前被调用,产生相同的随机数。
正如 zenith 所说,全局变量的初始化发生在 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},
};
但是全局变量通常不是一个好主意,依赖初始化顺序(仅在 objects 在同一翻译单元中初始化之间指定)尤其糟糕。
而是只使用局部变量:
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()
的工具,并可手动转换结果以生成特定分布。使用 header <random>
,使用 random_device
而不是 time(NULL)
创建和播种生成器,例如 std::mt19937
,并使用分布 objects:
#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]);
}
注意这是多么容易阅读,直接说明所需的间隔,而不是依赖于 %
如何处理负数。
(我什至不确定你原来的间隔是不是错误,但我已经忠实地复制了它们,假设 %
的常见行为是负数,直到 C+ 才标准化+11.)
我对 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,传递了当前时间。但是,每次程序出错时都会生成相同的随机数。我有什么不明白的?
全局变量将在进入main
之前初始化。
你的 objects
是一个全局变量,因为它是在任何函数之外声明的。
实际上,rand()
在 srand()
之前被调用,产生相同的随机数。
正如 zenith 所说,全局变量的初始化发生在 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},
};
但是全局变量通常不是一个好主意,依赖初始化顺序(仅在 objects 在同一翻译单元中初始化之间指定)尤其糟糕。
而是只使用局部变量:
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()
的工具,并可手动转换结果以生成特定分布。使用 header <random>
,使用 random_device
而不是 time(NULL)
创建和播种生成器,例如 std::mt19937
,并使用分布 objects:
#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]);
}
注意这是多么容易阅读,直接说明所需的间隔,而不是依赖于 %
如何处理负数。
(我什至不确定你原来的间隔是不是错误,但我已经忠实地复制了它们,假设 %
的常见行为是负数,直到 C+ 才标准化+11.)