how do I save a dynamically allocated vector and return as a pointer in the function?

Asked

Viewed 163 times

0

#include<stdio.h>
#include<stdlib.h>

void soma(float *vimp,float *vr ,int qnt, float *med, int a);
void maiorvalor(float *vimp, float mval, int qnt );

main(){
     float med, vimp, mval,vr;
     int qnt,i,a;

    printf("informe a quantidade de pessoas a serem fiscalizadas: \n");
    scanf("%d",&qnt);

    soma(&vimp,&vr, qnt, &med, a);
    maiorvalor(&vimp,mval,qnt);

    printf("a soma de todos os valores: %f\n", vr);
    printf("a media dos valores: %f\n", med);
    printf("o maior valor foi: %f\n",mval);
    printf("a quantidade de pessoas acima da media foi: %d\n",a);

    for(i=0;i<qnt;i++){
        printf(" %d valor : %f\n", i+1,vimp);
    }   
  system("pause");  
}
void soma(float *vimp, float *vr,int qnt, float *med, int a){
    int i;  
    vimp = (float*) malloc (qnt*sizeof(float));
    for(i=0;i<qnt;i++){
        printf("informe o valor em debito da %d%c pessoa\n",i+1,167);
        scanf("%f",vimp);

        *vr= *vimp+*vr;
        *med=*vr/qnt;
    }   

    for(i=0; i<qnt;i++){
        if(vimp>med){
            a++;
        }
    }  
}
void maiorvalor(float *vimp, float mval, int qnt){

    int i;

    for(i=0;i<qnt;i++){
        if(*vimp>mval){
            mval=*vimp;
        }
    }
}

1 answer

1


There are quite a few errors in the program, but I start by answering the question directly.

Vector return

To return a dynamically allocated vector, simply change its return type and use the keyword Return. In your role soma:

void soma( ...

Alters to:

float* soma(...

To play with the vector type. And now at the end of this function returns the allocated vector:

float* soma(...) {
    ...
    float *vimp = (float*) malloc (qnt*sizeof(float)); //alocação
    ...
    return vimp; //retorno
}

In the main has to capture properly:

int main(){
    ...
    float* vetor_capturado = soma(...);

Correction

Let’s start by correcting the program using vector return already. In several sites you are using *vimp directly being that the pointer points to the vector:

*vr= *vimp+*vr;

This way you won’t be able to access all the elements and only the first. Correct and simplify by changing to:

*vr += vimp[i];

Trying to change as little of your logic as possible so that the program works:

#include<stdio.h>
#include<stdlib.h>

//Retorna agora um vetor de floats e não recebe vimp.
//O parametro a é agora também passado como ponteiro
float* soma(float *vr ,int qnt, float *med, int *a);

//mval precisa de ser passado como ponteiro para ser alteravel
void maiorvalor(float *vimp, float *mval, int qnt );

int main(){
    float med, mval,vr;
    int qnt,i,a = 0; //faltava a=0

    printf("informe a quantidade de pessoas a serem fiscalizadas: \n");
    scanf("%d",&qnt);

    float* vimp = soma(&vr, qnt, &med, &a); //nova captura do vetor
    maiorvalor(vimp,&mval,qnt);

    printf("a soma de todos os valores: %f\n", vr);
    printf("a media dos valores: %f\n", med);
    printf("o maior valor foi: %f\n",mval);
    printf("a quantidade de pessoas acima da media foi: %d\n",a);

    for(i=0;i<qnt;i++){
        printf(" %d valor : %f\n", i+1,vimp[i]); //vimp[i] que faltava
    }

    free(vimp); //liberar a memoria alocada na função
    return 0;
}

float* soma(float *vr,int qnt, float *med, int *a){
    int i;
    float *vimp = (float*) malloc (qnt*sizeof(float));
    for(i=0;i<qnt;i++){
        printf("informe o valor em debito da %d%c pessoa\n",i+1,167);
        scanf("%f",&vimp[i]);
        *vr += vimp[i]; //simplificado
    }

    *med=*vr/qnt; //media so calculada no fim

    for(i=0; i<qnt;i++){
        if(vimp[i]>*med){ //faltava vimp[i] e *med
            (*a)++; //faltava *a
        }
    }

    return vimp; //novo retorno
}

void maiorvalor(float *vimp, float *mval, int qnt){
    int i;
    for(i=0;i<qnt;i++){
        if(vimp[i]>*mval){
            *mval=vimp[i];
        }
    }
}

See the result of this version in Ideone

It is important to note that the vector you were allocating in the function soma would generate a memory leak unless it was destroyed somewhere by you, and for that reason I also added the free in order to make clear their need.

Improvements

Although already working can improve in some aspects:

  • Variable and function names should be as evident as possible, and therefore a name like a is not at all good.
  • In this particular case of your program which is simple, it becomes easier not to have a priori declaration of the functions making each change need to be made only in one place.
  • Return the largest vector value as function return maiorvalor.

Applying these improvements:

#include<stdio.h>
#include<stdlib.h>

float* somar(float *soma,int qnt, float *media, int *acima_media){
    int i;
    float *debitos = malloc (qnt*sizeof(float));
    for(i = 0;i < qnt;i++){
        printf("informe o valor em debito da %d%c pessoa\n", i+1, 167);
        scanf("%f", &debitos[i]);
        *soma += debitos[i];
    }

    *media=*soma / qnt;

    for(i=0; i<qnt;i++){
        if(debitos[i]>*media){
            (*acima_media)++;
        }
    }
    return debitos;
}

float calcular_maior(float *debitos, int qnt){
    int i;
    float maior = debitos[0];
    for(i = 1;i < qnt;i++){
        if(debitos[i] > maior)
            maior = debitos[i];
    }
    return maior;
}

int main(){
    float media, soma;
    int qnt, acima_media = 0;

    printf("informe a quantidade de pessoas a serem fiscalizadas: \n");
    scanf("%d",&qnt);

    float* debitos = somar(&soma, qnt, &media, &acima_media);
    float maior = calcular_maior(debitos, qnt);

    printf("a soma de todos os valores: %f\n", soma);
    printf("a media dos valores: %f\n", media);
    printf("o maior valor foi: %f\n", maior);
    printf("a quantidade de pessoas acima da media foi: %d\n", acima_media);

    int i;
    for(i = 0;i<qnt;i++){
        printf(" %d valor : %f\n", i+1,debitos[i]);
    }

    free(debitos);
    return 0;
}

See also this second version on Ideone

Note that I haven’t done some health tests, such as ensuring that it doesn’t call the function calcular_maior sized 0 which will generate an invalid memory access.

Organizing with structures

Using structures can still further organize your code if you separate each part of the logic in the correct location. This way it can have a function only to read the values, and another only to totalize, and the latter would return the results all in a structure.

With this you can:

  • Not having to pass pointers to change what complicate logic
  • Separate the processing read

Final result:

#include<stdio.h>
#include<stdlib.h>

typedef struct Estatisticas {
    float soma;
    float media;
    float maior;
    int acima_media;
} Estatisticas;

float* ler_debitos(int qnt){
    int i;
    float *debitos = malloc (qnt * sizeof(float));
    for(i = 0;i < qnt;i++){
        printf("informe o valor em debito da %d%c pessoa\n", i+1, 167);
        scanf("%f", &debitos[i]);
    }

    return debitos;
}

Estatisticas totalizar(float* debitos, int qnt){
    Estatisticas totais = {0};    
    int i;
    for(i = 0; i < qnt;i++){
        totais.soma += debitos[i];
        if (debitos[i] > totais.maior){
            totais.maior = debitos[i];
        }
    }

    totais.media = totais.soma / qnt;

    for (i = 0; i < qnt;i++){
        if (debitos[i] > totais.media){
            totais.acima_media++;
        }
    }
    return totais;
}

int main(){
    int qnt;
    printf("informe a quantidade de pessoas a serem fiscalizadas: \n");
    scanf("%d",&qnt);

    float* debitos = ler_debitos(qnt);
    Estatisticas totais = totalizar(debitos, qnt);

    printf("a soma de todos os valores: %f\n", totais.soma);
    printf("a media dos valores: %f\n", totais.media);
    printf("o maior valor foi: %f\n", totais.maior);
    printf("a quantidade de pessoas acima da media foi: %d\n", totais.acima_media);

    int i;
    for(i = 0;i < qnt;i++){
        printf(" %d valor : %f\n", i+1, debitos[i]);
    }

    free(debitos);
    return 0;
}

See this latest version also on Ideone

Browser other questions tagged

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