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

8

I have a job for my course, and it is necessary to make a program similar to the megasena game. It's almost ready, but I'm finding a little problem and need help.
Data of the work: maximum of 10 players can bet, each one can bet from 6 up to 15 numbers in the interval [1.60].

In the sorteiaNumerosSena() function, I draw 6 random numbers and allocate them to a 6-position vector. This function is within the pegaApostasJogadores() function. I want to return the% c and% vector to the function and use it in another function to be displayed and compared to the players' bets. I can not 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);
            }
        }       
}
    
asked by anonymous 29.05.2014 / 23:08

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. Because the array is created locally, when the pointer is returned and used by the function that invoked DevolveArray(...) , the memory where the pointer points may no longer be array . This is because array was created in stack and when we exited from 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 inside the function and return a pointer to that array:

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

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

So another way to resolve the issue is to create a block of memory dynamically within DevolveArray(...) and return a pointer to the%

int* DevolveArray(int nTamanhoArray)
{
    int* pArray = malloc(sizeof(int) * nTamanhoArray);
    return pArray;
}

In this way, each call to array will create a new memory block (i.e. a new array). It should be noted that you have to pay attention to lifetime of DevolveArray(...) , that is, to 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.
Finally, in order to encapsulate the lifetime of the array on a single site you can choose to create 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);
}

In this way it ensures that the lifetime of the array is located in the array function which is responsible for creating and releasing the memory as needed.     

29.05.2014 / 23:54