How to make a function within a function return a vector?

Asked

Viewed 7,678 times

8

I have a job for my course, and it is necessary to make a program similar to the game of megasena. It’s almost done, but I’m finding a small problem and I need help.
Job dice: maximum 10 players can bet, each can bet from 6 up to 15 numbers in the range [1.60].

In function sorteiaNumerosSena(), I draw 6 random numbers and allocate them in a 6 position vector. This function is within the function pegaApostasJogadores(). I want to return the vector numerosApostas[] for the function and use it in another function to be displayed and compared to the bets of the players. I am not managing to return this vector. Could someone tell me a better solution or method to solve this? The complete code is just 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);
            }
        }       
}
  • 1

    A funny note: it seems that on both sides of the Atlantic one of the first programs is always the lottery/mega sena/Euromillions :)

  • 1

    ATTENTION: in C arrays are indexed 0 to n - 1. In your code you’re indexing 1 to n and therefore wasting 1 element and accessing another element that does not exist.

1 answer

3


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 above code has a problem. How the array is created locally, when the pointer is returned and used by the function you invoked DevolveArray(...), the memory to which the pointer points may no longer be the array. This is because the array was created in the stack and when we left DevolveArray(...) the space occupied by array can now be reused by other functions.

How to resolve the issue then?

One way is to create a static array within the function and return a pointer to that array:

int* DevolveArray()
{
    static int arrayExemplo[5];
    return arrayExemplo;
}

The problem with this approach is that in this way the array becomes global, that is, all calls to DevolveArray(...) will use the same memory block, which may lead to unexpected values in the array (among others).

Thus, another way to resolve the issue will be to create a block of memory dynamically within DevolveArray(...) and return a pointer to the array servant:

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 (i.e a new array). Note that you have to pay attention to Lifetime of array, that is, ensure that memory is released 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.

Lastly, in order to encapsulate the Lifetime of array in one place you can choose to create the array and pass it by 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 ensures that the Lifetime of array is located in one in the function ConsomeArray(...) who is responsible for creating and releasing the memory as needed.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.