2016-06-18 8 views
-2

Die Variable „initialisiert“ in dem Verfahren initRandomSeed()Kann ich hier globale Variable anstatt statische lokale Variable verwenden?

/* 
* File: random.cpp 
* ---------------- 
* This file implements the random.h interface. 
*/ 


#include <cstdlib> 
#include <cmath> 
#include <ctime> 
#include "random.h" 
#include "private/randompatch.h" 
using namespace std; 

/* Private function prototype */ 

static void initRandomSeed(); 

/* 
* Implementation notes: randomInteger 
* ----------------------------------- 
* The code for randomInteger produces the number in four steps: 
* 
* 1. Generate a random real number d in the range [0 .. 1). 
* 2. Scale the number to the range [0 .. N) where N is the number of values. 
* 3. Translate the number so that the range starts at the appropriate value. 
* 4. Convert the result to the next lower integer. 
* 
* The implementation is complicated by the fact that both the expression 
* 
*  RAND_MAX + 1 
* 
* and the expression for the number of values 
* 
*  high - low + 1 
* 
* can overflow the integer range. These calculations must therefore be 
* performed using doubles instead of ints. 
*/ 

int randomInteger(int low, int high) { 
    initRandomSeed(); 
    double d = rand()/(double(RAND_MAX) + 1); 
    double s = d * (double(high) - low + 1); 
    return int(floor(low + s)); 
} 

/* 
* Implementation notes: randomReal 
* -------------------------------- 
* The code for randomReal is similar to that for randomInteger, 
* without the final conversion step. 
*/ 

double randomReal(double low, double high) { 
    initRandomSeed(); 
    double d = rand()/(double(RAND_MAX) + 1); 
    double s = d * (high - low); 
    return low + s; 
} 

/* 
* Implementation notes: randomChance 
* ---------------------------------- 
* The code for randomChance calls randomReal(0, 1) and then checks 
* whether the result is less than the requested probability. 
*/ 

bool randomChance(double p) { 
    initRandomSeed(); 
    return randomReal(0, 1) < p; 
} 

/* 
* Implementation notes: setRandomSeed 
* ----------------------------------- 
* The setRandomSeed function simply forwards its argument to srand. 
* The call to initRandomSeed is required to set the initialized flag. 
*/ 

void setRandomSeed(int seed) { 
    initRandomSeed(); 
    srand(seed); 
} 

/* 
* Implementation notes: initRandomSeed 
* ------------------------------------ 
* The initRandomSeed function declares a static variable that keeps track 
* of whether the seed has been initialized. The first time initRandomSeed 
* is called, initialized is false, so the seed is set to the current time. 
*/ 

static void initRandomSeed() { 
    static bool initialized = false; 
    if (!initialized) { 
     srand(int(time(NULL))); 
     initialized = true; 
    } 
} 

Um sicherzustellen, dass der Initialisierungscode jedes Zeit nicht ausgeführt wird erhalten, müssen Sie eine Boolesche Flag aufzuzeichnen, ob die Initialisierung wurde durchgeführt. Leider funktioniert es nicht, das Flag als globale Variable zu deklarieren, weil C++ nicht die Reihenfolge in spezifiziert, welche globalen Variablen initialisiert werden. Wenn Sie andere globale Werte deklarieren, deren Anfangswerte von der zufälligen Bibliothek erstellt wurden, gibt es keine Möglichkeit sicherzustellen, dass das Initialisierungsflag korrekt festgelegt wurde.

Können Sie ein Beispiel: „Wenn Sie andere globale Werte, deren erklären Anfangswerte durch die zufällige Bibliothek erzeugt wurden, gäbe es keine Möglichkeit, um sicherzustellen, dass die Initialisierungsmerker richtig eingestellt worden war.“

+0

Sie denken wirklich die Frage eine direkte Referenz besser wird „das Buch“, um durch Entfernen (wäre es immer noch schön zu wissen, von wo du eingefügtes Zeug kopierst), während du immer noch einen kompletten Textblock zitierst? – user463035818

Antwort

0

Sie wollen für statische Initialisierung Fiasko suchen: https://cryptopp.com/wiki/Static_Initialization_Order_Fiasco

Zum Beispiel, wenn Sie eine globale Variable myInt zu erklären waren:

int myInt = initRandomSeed();

würde dies ausgeführt werden soll, bevor Ihr Programm den main() Block eintritt, und es gibt keine Garantie, dass initialized vor myInt

einrichten wird