Question:
I have a project for my course, and it is necessary to make a program similar to the megasena game. It's almost done, but I'm running into a little problem and I need help.
Job data: maximum 10 players can bet, each can bet from 6 to 15 numbers in the range [1.60].
In the sorteiaNumerosSena()
function, I draw 6 random numbers and allocate them in a 6-position vector. This function is inside the pegaApostasJogadores()
function. I want to return the numerosApostas[]
to the function and use it in another function to be displayed and compared with the players' bets. I am not able to return this vector. Could anyone point me to a solution or a better method to solve this? The complete code can be found below.
#include <stdio.h>
#include <locale.h>
#include <stdlib.h>
#include <time.h>
int pegaNumeroJogadores (); // Protótipo
int validaNumeroJogadores (int numeroJogadores); // Protótipo
int pegaApostasJogadores (int qtdeJogadores); // Protótipo
int validaQuantidadeApostas (int quantidadeApostas); // Protótipo
int validaApostaJogador (int apostaDoJogador); // Protótipo
int sorteiaNumerosSena (); // Protótipo
int mostraApostas (int contadorLinha, int contadorColuna, int apostasJogadores[][14], int *vetorApostas, int qtdeJogadores); // Protótipo
int verificaGanhador (int contadorLinha, int contadorColuna, int apostasJogadores[][14], int *vetorApostas, int qtdeJogadores, int *sorteados); // Protótipo
int main (void) {
// Declarações locais
int qtdeJogadores;
// Instruções
setlocale(LC_ALL, "Portuguese");
qtdeJogadores = pegaNumeroJogadores();
pegaApostasJogadores(qtdeJogadores);
return 0;
}
int pegaNumeroJogadores () {
// Declarações locais
int numeroJogadores;
// Instruções
printf("Insira a quantidade de jogadores\n> ");
scanf("%d", &numeroJogadores);
numeroJogadores = validaNumeroJogadores(numeroJogadores);
return numeroJogadores;
}
int validaNumeroJogadores (int numeroJogadores) {
// Declarações locais
// Instruções
while ((numeroJogadores <= 0) || (numeroJogadores > 10)) {
printf("Quantidade inválida de jogadores, insira novamente.\n> ");
scanf("%d", &numeroJogadores);
}
return numeroJogadores;
}
int pegaApostasJogadores (int qtdeJogadores) {
// Declarações locais
int contadorColuna, contadorLinha, quantidadeApostas, apostaDoJogador, vetorApostas[9], apostasJogadores[9][14], sorteados;
// Instruções
for (contadorLinha = 0; contadorLinha < qtdeJogadores; contadorLinha++) {
printf("Jogador de número %d, quantos números jogará?\n> ", contadorLinha+1);
scanf("%d", &quantidadeApostas);
vetorApostas[contadorLinha] = quantidadeApostas;
for (contadorColuna = 0; contadorColuna < quantidadeApostas; contadorColuna++) {
printf("%dº número da aposta: ", contadorColuna+1);
scanf("%d", &apostaDoJogador);
apostaDoJogador = validaApostaJogador(apostaDoJogador); /* Valida a aposta do jogador */
apostasJogadores[contadorLinha][contadorColuna] = apostaDoJogador;
}
}
system("cls");
sorteados = sorteiaNumerosSena();
printf("%d\n", sorteados);
mostraApostas(contadorLinha,contadorColuna,apostasJogadores,vetorApostas,qtdeJogadores);
verificaGanhador(contadorLinha,contadorColuna,apostasJogadores,vetorApostas,qtdeJogadores,sorteados);
}
int validaQuantidadeApostas (int quantidadeApostas) {
// Declarações locais
// Instruções
while ((quantidadeApostas < 6) || (quantidadeApostas > 15)) {
printf("Quantidade de apostas inválida, favor inserir outra.\n> ");
scanf("%d", &quantidadeApostas);
}
return quantidadeApostas;
}
int validaApostaJogador (int apostaDoJogador) {
// Declarações locais
// Instruções
while ((apostaDoJogador <= 0) || (apostaDoJogador > 60)) {
printf("Sua aposta é inválida, favor utilizar outra.\n> ");
scanf("%d", &apostaDoJogador);
}
return apostaDoJogador;
}
int sorteiaNumerosSena () {
// Declarações locais
static int numerosSorteio[6];
int contador, auxiliar, troca;
// Instruções
printf("SORTEIO DE 6 NÚMEROS ALEATÓRIOS\n");
srand((unsigned)time(NULL));
for (contador = 1; contador <= 6; contador++) {
numerosSorteio[contador] = (1+rand()%60);
for (auxiliar = 1; auxiliar <= contador; auxiliar++) {
if (numerosSorteio[auxiliar] == numerosSorteio[contador]) {
numerosSorteio[contador] = (1+rand()%60);
}
}
}
for (contador = 1; contador <= 6; contador++) {
for (auxiliar = contador+1; auxiliar <= 6; auxiliar++) {
if (numerosSorteio[contador] > numerosSorteio[auxiliar]) {
troca = numerosSorteio[auxiliar];
numerosSorteio[auxiliar] = numerosSorteio[contador];
numerosSorteio[contador] = troca;
}
}
//printf("Números sorteados: %d\n", numerosSorteio[contador]);
}
}
int mostraApostas (int contadorLinha, int contadorColuna, int apostasJogadores[][14], int *vetorApostas, int qtdeJogadores) {
// Instruções
for (contadorLinha = 0; contadorLinha < qtdeJogadores; contadorLinha++) {
printf("Apostas do %dº jogador: ", contadorLinha+1);
for (contadorColuna = 0; contadorColuna < vetorApostas[contadorLinha]; contadorColuna++) {
printf("%d ", apostasJogadores[contadorLinha][contadorColuna]);
}
printf("\n");
}
}
int verificaGanhador (int contadorLinha, int contadorColuna, int apostasJogadores[][14], int *vetorApostas, int qtdeJogadores, int *sorteados) {
// Declarações locais
int contador, acertos;
// Instruções
for (contadorLinha = 0; contadorLinha < qtdeJogadores; contadorLinha++) {
for (contadorColuna = 0; contadorColuna < vetorApostas[contadorLinha]; contadorColuna++) {
for (contador = 1; contador <= 6; contador++) {
if (apostasJogadores[contadorLinha][contadorColuna] == sorteados[contador]) {
acertos++;
}
}
}
if (acertos == 6) {
printf("Jogador %d, você acertou os 6 números! És o novo milionário nacional!!\n", contadorLinha+1);
}
else {
printf("Jogador %d, você obteve %d acertos.\n", contadorLinha+1,acertos);
}
}
}
Answer:
In C it is not possible to pass an array directly as a result of a function. You will have to return a pointer to the created array.
Example:
int* DevolveArray()
{
int arrayExemplo[5];
return arrayExemplo;
}
However the code above has a problem. As the array is created locally, when the pointer is returned and used by the function that invoked DevolveArray(...)
, the memory the pointer points to may no longer be the array
. This happens because the array
was created on the stack
and when we DevolveArray(...)
the space occupied by the array
can now be reused by other functions.
How to resolve the issue then?
One way is to create a static array inside the function and return a pointer to that array:
int* DevolveArray()
{
static int arrayExemplo[5];
return arrayExemplo;
}
The problem with this approach is that this way the array
becomes global, that is, all calls to DevolveArray(...)
will use the same memory block, which can lead to unexpected values in the array
(among others).
So, another way to solve the issue will be to dynamically create a memory block inside DevolveArray(...)
and return a pointer to the created array
:
int* DevolveArray(int nTamanhoArray)
{
int* pArray = malloc(sizeof(int) * nTamanhoArray);
return pArray;
}
In this way, each call to DevolveArray(...)
will create a new memory block (ie a new array). It should be noted that you have to pay attention to the lifetime of the array
, that is, ensure that memory is freed when it is no longer needed (otherwise there is a risk of creating memory leaks ):
free(pArray); // chamar a função free com o ponteiro do array criado.
Finally, in order to encapsulate the lifetime of the array
in a single place, you can choose to create the array
and pass it as a pointer to the function that will manipulate/change it:
void ModArray(int* pArray, int nSizeArray)
{
for(int i = 0; i < nSizeArray; ++i)
{
*(pArray + i) = i;
}
}
void ConsomeArray()
{
int nSize = 10;
int* pArray = malloc(sizeof(int) * nSize);
ModArray(pArray, nSize);
for(int i = 0; i < nSizeArray; ++i)
{
printf("ID %d: %d", i, *(pArray + i));
}
free(pArray);
}
This way it ensures that the lifetime of the array
is located in a ConsomeArray(...)
function that is responsible for creating and freeing memory as needed.