Reputation: 3
I am trying to generate some lotto numbers and return the array that contain these numbers but I cant go any further; Help please
void getLotto(int rad[7]) {
int numbers[7];
for (int i = 0; i < 7; i++) {
numbers[i] = rand() % 35 + 1;
}
for (int j = 0; j < 7; j++) {
int n = rand() % 35 + 1;
if (n == numbers[j]) {
numbers[j] = rand() % 35 + 1;
return;
}
}
}
Upvotes: 0
Views: 141
Reputation: 4409
There are two main ways of accomplishing this.
note: I'm not sure what your second for loop is doing. I guess the intention was to ensure that the numbers are all unique? You might want to take a look at it as that is not what it is doing. For the purposes of this question, I've cut it down to just generating the random numbers to populate the array.
The first is to take your code and fix it to put the generated numbers into the array that was passed in:
#include <iostream>
void getLotto(int numbers[7]) {
for (int i = 0; i < 7; i++)
{numbers[i] = rand() % 35 + 1;}
return;
}
int main()
{
srand(time(0));
int lotto_numbers[7];
getLotto(lotto_numbers);
for (int i = 0; i < 7; i++)
{std::cout<<lotto_numbers[i]<<std::endl;}
}
numbers
isn't actually passed in as an int[]
but instead as an int*
pointing to the array. This means that any changes you make to it in the function are changed in the original data.
Bear in mind that you need to keep track of your array bounds though, as the array could be defined as
int lotto_numbers[6]
which means that
numbers[7]
would be out of bounds.
The second method is to create the array on the heap. This means that you don't need to pass in an array but you can instantiate it in the function
I'm not actually going to provide the code for this here. Mainly because for something simple like this, the memory management is more trouble than it is worth. (you need to remember to call delete[]
for everything created on the heap etc).
Instead, lets use something with memory management built in:
#include <iostream>
#include <vector>
std::vector<int> getLotto() {
std::vector<int> numbers;
numbers.reserve(7);
for (int i = 0; i < 7; i++) {
//numbers[i] = rand() % 35 + 1;
//would work, but is unsafe as you could potentially reference somthing out of range
//this is safer:
numbers.push_back(rand() % 35 + 1);
}
return numbers;
}
int main()
{
srand(time(0));
std::vector<int> lotto_numbers = getLotto();
for (auto i = lotto_numbers.begin(); i != lotto_numbers.end(); i++)
{
std::cout<<*i<<std::endl;
}
}
The vector handles the memory management for you. The vector can be returned, and the returned vector will still point at the allocated memory on the heap we have just populated. We don't need to free it as this will be done automatically when the vector goes out of scope.
Upvotes: 0
Reputation: 483
C++ does not allow to return an entire array as an argument to a function. However, you can return a pointer to an array by specifying the array's name without an index.
If you want to return a single-dimension array from a function, you would have to declare a function returning a pointer as in the following example:
int * myFunction()
{
.
.
.
}
Second point to remember is that C++ does not advocate to return the address of a local variable to outside of the function so you would have to define the local variable as static variable.
Now, consider the following function, which will generate 10 random numbers and return them using an array and call this function as follows:
#include <iostream>
#include <ctime>
using namespace std;
// function to generate and retrun random numbers.
int * getRandom( )
{
static int r[10];
// set the seed
srand( (unsigned)time( NULL ) );
for (int i = 0; i < 10; ++i)
{
r[i] = rand();
cout << r[i] << endl;
}
return r;
}
// main function to call above defined function.
int main ()
{
// a pointer to an int.
int *p;
p = getRandom();
for ( int i = 0; i < 10; i++ )
{
cout << "*(p + " << i << ") : ";
cout << *(p + i) << endl;
}
return 0;
}
When the above code is compiled together and executed, it produces result something as follows
624723190
1468735695
807113585
976495677
613357504
1377296355
1530315259
1778906708
1820354158
667126415
*(p + 0) : 624723190
*(p + 1) : 1468735695
*(p + 2) : 807113585
*(p + 3) : 976495677
*(p + 4) : 613357504
*(p + 5) : 1377296355
*(p + 6) : 1530315259
*(p + 7) : 1778906708
*(p + 8) : 1820354158
*(p + 9) : 667126415
Upvotes: 0
Reputation: 1970
std::vector
and std::array
are better than regular arrays, but if you want to use regular arrays you can modify your function as follows:
// Arguments: renamed the array, added N (# of array elements)
void getLotto(int numbers[], size_t N) {
//int numbers[7]; // commented out local variable
for (int i = 0; i < N; i++) {
numbers[i] = rand() % 35 + 1;
}
for (int j = 0; j < N; j++) {
int n = rand() % 35 + 1;
if (n == numbers[j]) {
numbers[j] = rand() % 35 + 1;
return;
}
}
}
The brackets in int numbers[]
indicates that the argument is an array, and what is actually passed is a pointer to the first element of the array. Modifying numbers
in getLotto()
modifies the array passed to the function.
The second argument is of type size_t
because it is the platform-dependent alias for the unsigned integral type used by your system to represent the size of objects (like arrays).
This isn't as safe in that the function has to trust that numbers
actually has N
elements, but this is how you have a function modify a regular array instead of a container like std::vector
.
You would call the function like this:
size_t N;
int numbers[N];
getLotto(numbers, N);
Upvotes: 0
Reputation: 217085
Following may help, using Fisher–Yates_shuffle:
// Fisher–Yates_shuffle
// http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
std::vector<int> FisherYatesShuffle(std::size_t size, std::size_t max_size, std::mt19937& gen)
{
assert(size < max_size);
std::vector<int> res(size);
for(std::size_t i = 0; i != max_size; ++i) {
std::uniform_int_distribution<> dis(0, i);
std::size_t j = dis(gen);
if (j < res.size()) {
if (i != j) {
res[i] = res[j];
}
res[j] = 1 + i;
}
}
return res;
}
Upvotes: 0
Reputation: 96790
Arrays can't be returned by functions. A common thing to do is to dynamically allocate the array and return a pointer to its first element. This will work in your case but will generate a requirement for the caller to manage the memory (delete[]
the new[]
'ed memory). That's why C++ provides us with standard array classes: Use and return a std::vector
. If you have C++11 support, return std::array
.
Upvotes: 2