2016-06-18 6 views
-2

方法initRandomSeed(で「初期化」変数が)静的ローカル変数の代わりにグローバル変数を使用できますか?

/* 
* 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; 
    } 
} 

初期化コードは、すべての 時間が実行されないことを確実にするために、あなたはその初期 がされているかどうかを記録するために、ブール型のフラグを必要とします実行されます。残念ながら、 フラグをグローバル変数として宣言することはできません。なぜなら、C++はグローバル変数が初期化された の順序を指定していないからです。ランダムな ライブラリによって初期値が生成された他のグローバル 値を宣言すると、初期化フラグ が正しく設定されていることを確認する方法がありません。

あなたは「あなたがその初期値はランダム ライブラリーによって生成された他のグローバル 値を宣言する場合は、初期化フラグ が正しく設定されていたことを確実にする方法はありません。」の例を与えることができます

+0

前に設定されることを保証はありませんあなたは本当に質問は「ブック」への直接の言及を削除することによりよくなると思います(まだペーストされたものをどこからコピーするか知っているといいですが)それでもテキストの完全なブロックを引用していますか? – user463035818

答えて

0

あなたは静的初期化失態を検索する:https://cryptopp.com/wiki/Static_Initialization_Order_Fiasco

たとえば、グローバル変数ミン宣言した場合:

int型ミン= initRandomSeedを();あなたのプログラムがmain()のブ​​ロックに入る前に

これが実行になるだろう、とinitializedはミント

関連する問題