[C] Allocazione dinamica

bad.alex
Ciao a tutti.
Vorrei chiedere il vostro aiuto per un esercizio in cui si chiede:
"Si consideri un vettore v[] di 100 numeri reali e lo si riempia con 100 elementi generati casualmente attraverso la funzione rand().
Scrivere la funzione "filter_vector" che, fornito il vettore v[] come parametro in_vector[] restituisce un nuovo vettore allocato dinamicamente, il quale contiene soltanto gli elementi v che soddisfano la relazione:
invector +0.2*invector[i-1]+0.03*invector[i-2]<32000
si consideri che la funzione dovrà restituire sia il nuovo vettore sia le dimensioni del nuovo vettore e pertanto avrà il seguente prototipo:
float * filter_vector(float *in_vector, int in_vector_size, int *out_vector_size)

Si chiede inoltre di stampare il nuovo vettore ( con apposita funzione) e di calcolare, tramite funzioni, i valori massimo e minimo del nuovo vettore e di stamparli".

Io trovo parecchie difficoltà nell'impostare l'esercizio. Vi riporto quanto svolto, in maniera confusionaria, sinora:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <time.h>


#define N 100

float riempi_vettore ( float *a, int size) {
      int i; 
      
      for( i=0; i<=size-1; i++) 
           a[i]=rand();   
           a = malloc( (size) * sizeof(float));    
      }
      
float *filter_vector (float *in_vector, int in_vector_size, int * out_vector_size) {
      float                      ;
      int                        ;
      
      
      
      
      
      }
      
void stampa_vettore(int * filter_vector, int size) {

     int i;
     printf("Stampa nuovo vettore\n");
     for (i = 0; i < size; i++) {
         printf("filter_vector[%d]=%d\n", i, *filter_vector);
     }
}
      

float calcola_max(float *filter_vector, int N)
{
      float max;
      int i;
      max = filter_vector[0];
      for (i = 1; i < N; i++) {
          if (filter_vector[i] > max) max = filter_vector[i];
      }
      printf( "Il valore massimo del nuovo vettore è:\n", max);
}

float calcola_min(float * filter_vector, int size)
{
      float min;
      int i;
      min = filter_vector[0];
      for (i = 1; i < size; i++) {
          if (filter_vector[i] < min) min = filter_vector[i];
      }
      printf( "Il valore minimo del nuovo vettore è:\n", min);
}      


int main (void) {


system ("pause"); 
}

Purtroppo non è molto, anche perchè non riesco a capire come impostare i vari punti dell'esercizio, come svolgerli passo dopo passo....
Spero qualcuno di voi riesca ad aiutarmi.


Grazie


Alex

Risposte
bad.alex
Ragazzi, ho corretto il programma e adesso al momento della compilazione non vengono rilevati errori :)
Però, quando eseguo il programma l'unica cosa che appare è: riempi vettore con valori casuali (come da printf), stampa vettore ( e vengono riempiti i vettori da 0 a 99) e infine "il nuovo vettore è" ( ma non appare nulla).
Ancora qualcosa mi sfugge...

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

#define N 100

/* Dichiarazioni funzioni */
void riempi_vettore ( float *v, int size);
void stampa_vettore (float *v, int size);
float *filter_vector( float *in_vector, int in_vector_size, int * out_vector_size);
float calcola_max(float * out_v, int size_v, int out_size);
float calcola_min(float * out_v, int size_v, int out_size);



int main (void) {
    float a[N], max, min, *out;
    int i, out_size; 


printf( "Riempi vettore con valori casuali \n");
riempi_vettore(a,N);
printf("Stampa vettore\n");
stampa_vettore (a, N);
printf( "Il nuovo vettore e':\n");
out = filter_vector (a, N, &out_size);  
printf("la dim del vettor in uscita e' %d\n" , out_size);
    
    
for(i=0; i<out_size; i++){
printf("out[%d]=%f\n" , i , out[i]);
                              }
calcola_max(a , N , out_size);
calcola_min(a , N , out_size);

free (filter_vector);
system ("pause");

            }
            
/* Funzioni */

void riempi_vettore ( float *v, int size) {
      int i; 
      
      srand((unsigned)time(NULL));
      
      for( i=0; i<size; i++) {
           v[i]=rand();       
      }
} 

void stampa_vettore (float *v, int size)
 {  
     int i;
     for (i=0; i<size; i++) {
         printf("v[%d]=%f\n", i, v[i]);
         }
     }
     

     
float *filter_vector (float *in_vector, int in_vector_size, int * out_vector_size) {
      float   *out_vector, value;
      int         i  ;
      
      out_vector_size = 0;
      for(i=2; i<(in_vector_size); i++){
               if((in_vector[i]+(0.2*in_vector[i-1])+(0.03*in_vector[i-2]))<32000){
               out_vector_size=out_vector_size+1;
                                                                       }
                                                                  }
      
      out_vector = (float*)malloc((*out_vector_size)*sizeof(float));
      
      for (i=2; i<in_vector_size; i++) {
          value = in_vector[i] + 0.2*in_vector[i-1]+0.03*in_vector[i-2];
          if (value <32000) 
          {
                    out_vector[i]=value;
                    }
          }
          return out_vector; 
          }
      


float calcola_max(float *out_v, int size_v, int out_size)
{
      float max, *out;
      int i;
       out = filter_vector (out_v, size_v, &out_size); 
           max = out[0];
      for (i = 1; i < out_size-1; i++) {
          if (out[i] > max) max = out[i];
      }
      printf( "Il valore massimo del nuovo vettore è %f:\n", max);
      
return max;
}

float calcola_min(float * out_v, int size_v, int out_size)
{
      float min, *out;
      int i;
      
      out = filter_vector (out_v, size_v, &out_size);
      min = out[0];
      for (i = 1; i < out_size-1; i++) {
          if (out[i] < min) min = out[i];
      }
      printf( "Il valore minimo del nuovo vettore è %f:\n", min);
      
return min;
}      

vict85
Alcune correzioni veloci.

Qui hai dimenticato di seguire qualche nostro consiglio (alcuni dei quali li avevo sbagliati anche io nel mio messaggio)...
float *filter_vector (float *in_vector, int in_vector_size, int *out_vector_size) {
    float   *out_vector, value;
    int         i, j=0;

    *out_vector_size = 0;
    for (i=2; i<(in_vector_size); i++) {
        if ((in_vector[i]+(0.2*in_vector[i-1])+(0.03*in_vector[i-2]))<32000) {
            (*out_vector_size) = (*out_vector_size)+1;
        }
    }

    out_vector = (float*)malloc((*out_vector_size)*sizeof(float));

    for (i=2; i<in_vector_size; i++) {
        value = in_vector[i] + 0.2*in_vector[i-1]+0.03*in_vector[i-2];
        if (value <32000)
        {
            out_vector[j]=value;
            j++;
        }
    }
    return out_vector;
}


e nel main dovresti mettere
free(out);
invece di un enigmatico
free (filter_vector);
che tra l’altro mingw, sul mio pc, segna come errore.

Non ho però ancora controllato il resto.

vict85
Ok, trovato altri due errori semigravi. Per simmetricità ti mostrerò solo però quelli per calcola_max. L'errore è semigrave perché è legato al design e alla logica della programmazione, seppur sia innocuo in termini di risultato.

Tu carichi in calcola_max il vettore iniziale e poi ricalcoli il vettore ridotto. Ma tu hai già calcolato il vettore ridotto! Il metodo corretto sarebbe quindi implementare calcola_max (similmente per calcola_min) nel seguente modo:

float calcola_max(float *v, int v_size)
{
    float max;
    int i;
    max = v[0];
    for(i = 1; i != v_size; i++) {
        if (v[i] > max) max = v[i];
    }
    printf( "Il valore massimo del nuovo vettore e' %f:\n", max); 

    return max;
}


ovviamente ricordati anche di queste modifiche:
float calcola_max(float *v, int v_size);
float calcola_min(float *v, int v_size);

e
calcola_max(out , out_size);
calcola_min(out , out_size);


Con queste modifiche (ho modificato anche calcola_min) sembra funzionare tutto bene.

bad.alex
Grazie Vict. Vorrei chiederti una cosa: come mai considero il puntatore di out_vector_size?
Per quanto riguarda il massimo e il minimo: mi sono complicato la vita!!
Io ho mandato in esecuzione il programma ( privo di errori) ma al "il nuovo vettore è" continua a chiudersi improvvisamente la finestra...
Ti ringrazio per il prezioso aiuto!

vict85
"bad.alex":
Grazie Vict. Vorrei chiederti una cosa: come mai considero il puntatore di out_vector_size?


Perché ho bisogno di far conoscere il valore di out_vector_size al di fuori della funzione. Ho l’impressione che tu non abbia colto molto a fondo i vari concetti di funzione e puntatori in C.

"bad.alex":
Per quanto riguarda il massimo e il minimo: mi sono complicato la vita!!


Più che complicarsi la vita ritengo i tuoi errori siano, come detto sopra, dovuti a lacune nella tua comprensione del linguaggio e della programmazione in genere. Dovresti leggerti qualche dispensa o libro (mettersi a spiegarti tutte queste cose in questa sede sarebbe troppo lungo).

"bad.alex":
Io ho mandato in esecuzione il programma ( privo di errori) ma al "il nuovo vettore è" continua a chiudersi improvvisamente la finestra...
Ti ringrazio per il prezioso aiuto!


Strano, a me funziona.

Questo è il codice che ho compilato e lanciato io:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 100

/* Dichiarazioni funzioni */
void riempi_vettore ( float *v, int size);
void stampa_vettore (float *v, int size);
float *filter_vector( float *in_vector, int in_vector_size, int * out_vector_size);
float calcola_max(float *v, int v_size);
float calcola_min(float *v, int v_size);



int main (void)
{
    float a[N], max, min, *out;
    int i, out_size;


    printf( "Riempi vettore con valori casuali \n");
    riempi_vettore(a,N);
    printf("Stampa vettore\n");
    stampa_vettore (a, N);
    printf( "Il nuovo vettore e':\n");
    out = filter_vector (a, N, &out_size);
    printf("la dim del vettor in uscita e' %d\n" , out_size);


    for (i=0; i<out_size; i++) {
        printf("out[%d]=%f\n" , i , out[i]);
    }

    calcola_max(out , out_size);
    calcola_min(out , out_size);

    free(out);
    //system ("pause");

}

/* Funzioni */

void riempi_vettore ( float *v, int size)
{
    int i;

    srand((unsigned)time(NULL));

    for ( i=0; i<size; i++) {
        v[i]=rand();
    }
}

void stampa_vettore (float *v, int size)
{
    int i;
    for (i=0; i<size; i++) {
        printf("v[%d]=%f\n", i, v[i]);
    }
}



float *filter_vector (float *in_vector, int in_vector_size, int *out_vector_size)
{
    float   *out_vector, value;
    int         i, j=0;

    *out_vector_size = 0;
    for (i=2; i<(in_vector_size); i++) {
        if ((in_vector[i]+(0.2*in_vector[i-1])+(0.03*in_vector[i-2]))<32000) {
            (*out_vector_size) = (*out_vector_size)+1;
        }
    }

    out_vector = (float*)malloc((*out_vector_size)*sizeof(float));

    for (i=2; i<in_vector_size; i++) {
        value = in_vector[i] + 0.2*in_vector[i-1]+0.03*in_vector[i-2];
        if (value <32000)
        {
            out_vector[j]=value;
            j++;
        }
    }
    return out_vector;
}



float calcola_max(float *v, int v_size)
{
    float max;
    int i;
    max = v[0];
    for(i = 1; i != v_size; i++) {
        if (v[i] > max) max = v[i];
    }
    printf( "Il valore massimo del nuovo vettore è %f:\n", max);

    return max;
}

float calcola_min(float *v, int v_size)
{
    float min;
    int i;
    min = v[0];
    for(i = 1; i != v_size; i++) {
        if (v[i] < min) min = v[i];
    }
    printf( "Il valore massimo del nuovo vettore è %f:\n", min);

    return min;
}

bad.alex
a me continua a chiudersi improvvisamente la finestra, anche facendo copia incolla.
Si, non nego non abbia io capito i concetti o ciò che ci sta dietro puntatori e funzioni. Ho già seguito il deitel, per quanto riguada la parte teoria, e varie dispense presenti in internet ( tra cui anche quella del sito html). Ma alcune cose ancora non riesco a comprenderle, anche perchè non sempre si ricevono delucidazioni in merito a dubbi. Ti ringrazio, Vict!

vict85
Prova a togliere le due // prima del system("PAUSE"), sul mio sistema l'ho commentato perché non ce n'era bisogno. Ma se usi dev-c++ o non hai impostato il tutto per essere una applicazione console ti si chiude.

bad.alex
Grazie! Sbadatamente, non mi sono accorto della loro presenza.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.