简体   繁体   English

用随机数初始化的对象

[英]Object initialized with random numbers

I'm pretty new to c++ and oo, so this is probably something pretty silly. 我是C ++和oo的新手,所以这可能很愚蠢。 This is all in the code right after my include statements. 这些都在我的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},
}

I make a call to srand, passing in the current time, in my main method. 我用我的主要方法打电话给srand,并传递了当前时间。 However, this is generating the same random numbers every time the program is wrong. 但是,这在每次程序出错时都会生成相同的随机数。 What am I not understanding? 我不明白什么?

As zenith says, Initialization of globals happens before main() . 正如zenith所说的那样,全局变量的初始化发生在main()之前。 You could get srand() to run first as well by doing something like declaring a global variable with initialization that calls srand() , and which comes before the initialization of your static object objects[] : 您可以通过执行类似的操作来声明srand() ,该全局变量在初始化static object objects[]之前进行初始化,从而使srand()首先运行:

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},
};

But global variables are generally a bad idea anyway, and relying on things like initialization order (which is only well specified between objects initialized in the same translation unit) is particularly bad. 但是无论如何,全局变量通常都不是一个好主意,而依赖初始化顺序(只能在同一翻译单元中初始化的对象之间很好地指定)之类的事情就特别糟糕。

Instead just use local variables: 而是只使用局部变量:

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]);
}

The C++ standard library now provides facilities superior to srand() , rand() , and manually transforming the results to generate particular distributions. 现在,C ++标准库提供了优于srand()rand() ,并可以手动转换结果以生成特定的分布。 Use the header <random> , create and seed a generator such as std::mt19937 using random_device instead of time(NULL) , and use distribution objects: 使用标头<random> ,使用random_device代替time(NULL)创建并播种诸如std::mt19937类的生成器,并使用分发对象:

#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]);
}

Note how much easier this is to read, right down to directly stating the desired intervals, rather than relying on how % behaves with negative numbers. 请注意,这很容易阅读,直达直接说明所需的时间间隔,而不是依赖于%在负数上的表现。

(I'm not even sure your original intervals weren't mistakes, but I've faithfully reproduced them assuming the common behavior for % with negative numbers, which wasn't even standardized until C++11.) (我什至不确定您的原始间隔不是错误,但我忠实地复制了它们,并假定%的常见行为带有负数,直到C ++ 11才标准化。)

Global variables will be initialized before entering main . 全局变量将输入main 之前初始化。

Your objects is a global variable, because it's declared outside any function. 您的objects是全局变量,因为它是在任何函数外部声明的。

Effectively, rand() gets called before srand() , resulting in the same random numbers. 实际上, rand()srand()之前被调用,导致相同的随机数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM