简体   繁体   中英

Object initialized with random numbers

I'm pretty new to c++ and oo, so this is probably something pretty silly. This is all in the code right after my include statements.

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. 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() . 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[] :

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. Use the header <random> , create and seed a generator such as std::mt19937 using random_device instead of time(NULL) , and use distribution 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]);
}

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.)

Global variables will be initialized before entering main .

Your objects is a global variable, because it's declared outside any function.

Effectively, rand() gets called before srand() , resulting in the same random numbers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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