生成随机数并将它们放入数组中
generate random numbers and put them in an array
我想用 C++ 编写一个名为 Farkle 的小骰子游戏(您可能从 Kingdom come deliverance 知道它),但我仍在学习,所以我遇到了一些麻烦。
atm 我正在尝试掷 6 个骰子并将每个掷出的数字放在一个数组中,以便以后可以使用它。一切似乎工作正常,但 Visual Studio 输出此错误代码:
Run-Time Check Failure #2 - Stack around the variable 'die' was corrupted.
这是我的代码:
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
void dice() {
int die[5];
int i = 1;
while (i <= 6) {
die[i] = rand() % 6 + 1;
cout << die[i];
i++;
}
}
int main()
{
srand(time(NULL));
dice();
system("STOP");
return 0;
}
对于这种程序,这实际上是正确的方法吗?
试试这个代码:
#include <iostream>
#include <cstdlib>
#include <ctime>
void populateArray( int ar[], /*const*/ int n )
{
for( int i = 0 ; i < n ; ++i ) ar[i] = std::rand() % 50 + 1 ;
}
int main()
{
// http://en.cppreference.com/w/cpp/numeric/random/srand
std::srand( std::time(nullptr) ) ; // **** important ****
const int ARRAY_SIZE = 50;
int ar[ARRAY_SIZE] = {0} ;
populateArray( ar, ARRAY_SIZE ) ;
for( int v : ar ) std::cout << v << ' ' ;
}
index i
应该是从 0
到 5
,而不是 1
到 6
。
很明显,当i = 6
时,运行超出了dice
的范围,这就出错了。
编辑这些行:
int i = 0;
while (i <= 5) {
....
您的代码有 2 个问题:
数组的大小是 5,但是你访问了 6 个索引(1 到 6),你可以通过将条件中的 <=
更改为 <
来避免这种情况.
C++ 中数组的索引从 0 开始,但您从 1 开始。如果您将代码中的每个 die[i]
更改为 die[i-1]
,就可以解决这个问题。
另一种方法(解决这两个问题)是初始化 i=0
并使用 while (i < 5)
不,生成均匀分布随机数的更好方法是
#include <random>
#include <algorithm>
std::random_device rd; //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<> d6(1, 6); // {1, 2, 3, 4, 5, 6} with equal probability
int die[5];
std::generate(die, die + 5, [&gen, &d6](){ return d6(gen); });
如果您生成多组 5d6,您可以 re-use 相同 gen
而不是每次 re-initialising
正如其他人指出的那样。您的错误源于使用的数组太小。 post 将更多地说明您的代码更像 C。
在 C++ 中更习惯使用 std::array
而不是原始数组。
此外,建议不要使用 rand()
,因为它会产生错误的随机数,并且通过使用模运算,您会为随机数引入额外的偏差。相反,应该使用 <random>
header.
中的 类
为了使代码更具可读性,您可以尝试使用 <algorithm>
中的函数来通过命名算法替换您的循环。
这导致以下代码:
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <random>
void dice() {
std::array<int, 6> die;
std::mt19937 gen{std::random_device{}()};
std::uniform_int_distribution<int> dice_roll{1, 6};
std::generate(begin(die), end(die), [&] { return dice_roll(gen); });
std::copy(begin(die), end(die), std::ostream_iterator<int>{std::cout});
}
int main() {
dice();
std::cin.get();
}
我想用 C++ 编写一个名为 Farkle 的小骰子游戏(您可能从 Kingdom come deliverance 知道它),但我仍在学习,所以我遇到了一些麻烦。 atm 我正在尝试掷 6 个骰子并将每个掷出的数字放在一个数组中,以便以后可以使用它。一切似乎工作正常,但 Visual Studio 输出此错误代码:
Run-Time Check Failure #2 - Stack around the variable 'die' was corrupted.
这是我的代码:
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
void dice() {
int die[5];
int i = 1;
while (i <= 6) {
die[i] = rand() % 6 + 1;
cout << die[i];
i++;
}
}
int main()
{
srand(time(NULL));
dice();
system("STOP");
return 0;
}
对于这种程序,这实际上是正确的方法吗?
试试这个代码:
#include <iostream>
#include <cstdlib>
#include <ctime>
void populateArray( int ar[], /*const*/ int n )
{
for( int i = 0 ; i < n ; ++i ) ar[i] = std::rand() % 50 + 1 ;
}
int main()
{
// http://en.cppreference.com/w/cpp/numeric/random/srand
std::srand( std::time(nullptr) ) ; // **** important ****
const int ARRAY_SIZE = 50;
int ar[ARRAY_SIZE] = {0} ;
populateArray( ar, ARRAY_SIZE ) ;
for( int v : ar ) std::cout << v << ' ' ;
}
index i
应该是从 0
到 5
,而不是 1
到 6
。
很明显,当i = 6
时,运行超出了dice
的范围,这就出错了。
编辑这些行:
int i = 0;
while (i <= 5) {
....
您的代码有 2 个问题:
数组的大小是 5,但是你访问了 6 个索引(1 到 6),你可以通过将条件中的
<=
更改为<
来避免这种情况.C++ 中数组的索引从 0 开始,但您从 1 开始。如果您将代码中的每个
die[i]
更改为die[i-1]
,就可以解决这个问题。
另一种方法(解决这两个问题)是初始化 i=0
并使用 while (i < 5)
不,生成均匀分布随机数的更好方法是
#include <random>
#include <algorithm>
std::random_device rd; //Will be used to obtain a seed for the random number engine
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
std::uniform_int_distribution<> d6(1, 6); // {1, 2, 3, 4, 5, 6} with equal probability
int die[5];
std::generate(die, die + 5, [&gen, &d6](){ return d6(gen); });
如果您生成多组 5d6,您可以 re-use 相同 gen
而不是每次 re-initialising
正如其他人指出的那样。您的错误源于使用的数组太小。 post 将更多地说明您的代码更像 C。
在 C++ 中更习惯使用 std::array
而不是原始数组。
此外,建议不要使用 rand()
,因为它会产生错误的随机数,并且通过使用模运算,您会为随机数引入额外的偏差。相反,应该使用 <random>
header.
为了使代码更具可读性,您可以尝试使用 <algorithm>
中的函数来通过命名算法替换您的循环。
这导致以下代码:
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <random>
void dice() {
std::array<int, 6> die;
std::mt19937 gen{std::random_device{}()};
std::uniform_int_distribution<int> dice_roll{1, 6};
std::generate(begin(die), end(die), [&] { return dice_roll(gen); });
std::copy(begin(die), end(die), std::ostream_iterator<int>{std::cout});
}
int main() {
dice();
std::cin.get();
}