[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
apatriarca
Utilizza il tag code per inserire il codice. E' particolarmente importante quando si lavora su array perché le parentesi graffe sono usate per delimitare i tag in BBCODE. Per questa volta l'ho fatto io.

Ho dato una occhiata molto veloce al codice, ma l'impressione è che non ci sia praticamente alcuna funzione corretta, neanche quelle di creazione e visualizzazione dell'array di float. Ti consiglio quindi di lasciare per ora perdere l'esercizio che devi fare e iniziare con un programma che genera 100 numeri reali, li inserisca in un vettore e quindi stampi i valori di questo array. Dopo essere riuscito a completare questo primo programma avrà senso occuparsi del resto (il cui significato non credo che sia troppo chiaro). Inizio quindi a darti qualche suggerimento per fare questa prima parte del programma:
1. L'array deve essere allocato prima di iniziare a popolarlo e la dimensione dell'array è uguale a sizeof(float)*N. L'array deve essere allocato una sola volta e quindi al di fuori del ciclo in cui inserisci i valori nell'array. Alla fine del programma sarebbe opportuno deallocare la memoria chiamando free.
2. Scrivi il programma in modo "iterativo", aggiungendo di volta in volta le funzionalità e arrivando spesso a punti in cui sia possibile compilare e testare il programma. In questo modo puoi trovare subito gli errori e puoi essere più o meno sicuro della parte del codice in cui cercare il problema. Ti permette inoltre di verificare la corretta apertura e chiusura di tutte le parentesi graffe e se il programma che è stato scritto corrisponde effettivamente a quello che si desiderava scrivere.
3. Anche se stai lavorando con un puntatore, puoi comunque usare le parentesi graffe per accedere ad una posizione nell'array. L'uso degli indici al posto dell'aritmetica dei puntatori è spesso preferibile per un principiante perché il codice è di solito molto più leggibile. Per esempio, nella seguente riga della funzione per visualizzare l'array:
printf("filter_vector[%d]=%d\n", i, *filter_vector);

avresti dovuto scrivere:
printf("filter_vector[%d]=%d\n", i, filter_vector[i]);


Per ora direi che i suggerimenti dovrebbero bastare..

bad.alex
Ti ringrazio per avermi risposto. Si, sto studiando questi argomenti su libri di testo ( Deitel) ma anche seguendo i vari tutorial presenti su internet, ma ancora non riesco a capire bene come creare programmini un pò più complicati del programma standard "Hello World". Ho provato a seguire i tuoi consigli ( non so se sono riuscito però a seguirli correttamente) e di sotto ti riporto quanto fatto:


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

#define N 100

float riempi_vettore ( float *a, int size) {
      int i; 
      
a = malloc( (size) * sizeof(float));    
      for( i=0; i<=size-1; i++) 
           a[i]=rand();   
                 }
      
void stampa_vettore(int *a, int size)
{
     int i;
     for (i = 0; i < size; i++) {
         printf("a[%d]=%d\n", i, a[i]);
     }
}

int main (void) {
    float v[N];
    int i; 
    
    printf("Generazione di valori casuali\n");
      riempi_vettore(v, N);
      for (i = 0; i < N;i++) {
          printf("Indice %d, vett= %f\n",
                         i, v[i]);
      }
    
system ("pause");     
}

Io ho parecchie difficoltà con l'allocazione dinamica, anche per semplice richieste come nell'esercizio di cui ho riportat il testo...


apatriarca
Il codice è già un po' meglio di prima, anche se non ancora corretto. Partirei dalla funzione riempi_vettore. Ha come tipo del valore di ritorno float, ma non restituisci nulla dalla funzione ed in effetti non ha neanche senso che restituisca qualcosa. Dovrebbe quindi restituire void. Il vettore v è inoltre già allocato staticamente nel main e non è quindi necessario riallocarlo anche in riempi_vettore. Soprattutto perché non stai comunque restituendo questo vettore. La tua funzione per riempire il vettore la scriverei quindi così:
void riempi_vettore(float *a, int size)
{
    int i;
    srand((unsigned)time(NULL));

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

Ho aggiunto il blocco intorno al corpo del ciclo perché preferisco farlo anche quando non è necessario. Ma era corretto. Ho anche modificato la condizione del ciclo da i <= size - 1 a i < size in quanto equivalenti e la seconda è più leggibile e "standard". Ho anche aggiunto la chiamata alla funzione srand che serve per inizializzare il generatore di numeri casuali. Devi includere time.h per chiamare la funzione che ho usato per generare il seme usato dal generatore.

La funzione di stampa è quasi corretta. L'unico errore è che devi stampare un array di float e non di interi. Per cui devi cambiare il tipo del parametro e la stringa di formato del printf in modo che si aspetti un float.
void stampa_vettore(float *a, int size)
{
    int i;
    for (i = 0; i < size; i++) {
        printf("a[%d]=%f\n", i, a[i]);
    }
}


Il main è corretto. Però non è chiaro perché visualizzi l'array con un ciclo invece di usare la funzione che hai implementato.. system("PAUSE") non è necessario se si usa un IDE decente o si lanciano i programmi da linea di comando. L'avrei insomma scritta come segue:
int main(void)
{
    float v[N];

    printf("Generazione di valori casuali\n");
    riempi_vettore(v, N);
    stampa_vettore(v, N);

    return 0;
}


L'ultimo commento che posso fare è che malloc.h non è necessario in quanto malloc e free sono inclusi già da stdlib.h e malloc.h non è standard anche se abbastanza diffuso.

bad.alex
Si, effettivamente hai ragione sul ciclo for nel main. Una volta scritta la funzione, è inutile ricorrere al ciclo.
Adesso, stavo provando a svolgere il primo punto dell'esercizio, quello in cui si chiede di scrivere la funzione "filtro", una volta fornito il vettore a[] come parametro ( non capisco però cosa si intenda per parametro) in_vector, in modo tale che restituisca un nuovo vettore allocato dinamicamente e contenente solo gli elementi a soddisfacenti la condizione
invector+0.2*invector[i-1]+0.03*invector[i-2]<32000


Da quel che ho capito, io devo scrivere la mia funzione "filtro" ricorrendo ovviamente al prototipo:

float * filter_vector(float *in_vector, int in_vector_size, int *out_vector_size) {

....

}

Ciò che mi serve (al posto dei puntini) sarà un intero i che mi serve per trovare quei vettori a tali da soddisfare la richiesta invector+....<32000
Quindi devo ricorrere ad un ciclo for( i=0; i....<32000, in modo tale da trovare quei valori a ed inserirli nel nuovo vettore.
Al momento, ciò che mi ritrovo (anche se ben poco) è:

float * filter_vector(float *in_vector, int in_vector_size, int *out_vector_size) {

float *out_vector;
int i; 

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



}
}


Non mi è chiaro perchè la dimensione del vettore out_vector sia un puntatore e soprattutto non capisco dove mi occorre utilizzarla. Inoltre, non saprei come inserire nel nuovo vettore quei valori trovati all'interno del ciclo for imponendo l'if...
So che vado molto ma molto piano ma chiedo il tuo aiuto e i tuoi suggerimenti per capire qualcosa in più, che con i libri, non sempre è facile da apprendere o da comprendere.
Ti ringrazio

claudio862
Innanzitutto i deve partire da 2, non da 0, perché ad ogni iterazione controlli anche in_vector[i-2]. E deve arrivare ad in_vector_size, non in_vector (che ha poco senso).

La dimensione di out_vector viene calcolata dentro la funzione filter_vector, che la comunica al chiamante scrivendola all'indirizzo di out_vector_size.

Mi vengono in mente due possibilità:

1:
- Scorri l'array contando quanti indici i soddisfano la tua condizione (= K).
- Crei un nuovo array di K elementi.
- Scorri di nuovo l'array iniziale, inserendo nel secondo array tutti gli elementi che soddisfano la condizione (devi tenere traccia della posizione in cui hai inserito l'ultimo elemento, es. l'elemento all'indice 7 dell'array iniziale non sarà necessariamente all'indice 7 del secondo array).

2:
- Crei un nuovo array di N elementi.
- Scorri l'array iniziale, inserendo nel secondo array tutti gli elementi che soddisfano la condizione (e contandoli = K).
- Chiami realloc sul secondo array, ridimensionandolo a K elementi.

Alla fine assegni *out_vector_size = K e restituisci il secondo array.

bad.alex
Ti ringrazio, Claudio.
Io ho provato a svolgerlo in questo modo ma qualcosa non va ( inoltre vorrei scrivere nuovo vettore e dimensione del nuovo vettore utilizzano il prototipo fornito nel testo... ma non sono capace).
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 100


void riempi_vettore (float *v, int size);
int dimensione_vettore (float *in_vector, int size);
float * filter_vector(float * in_vector, int in_vector_size, int *out_vector_size);
float calcola_max(float * v, int size);
float calcola_min(float * v, int size);
int conteggio (float *v, int size);


int main (void) {
    float a[100], *out, *filtro, max, min;
    int i, dim, count;
    srand(time(NULL));
    
    riempi_vettore ( a, N);
    for (i=0; i<N; i++) {
        printf (" a[%d]=%f \n", i, a[i]);    
        }
    dim= dimensione_vettore (a, N);
    printf( " La dimensione del vettore in uscita e' %d\n", dim);
    out =(float*)malloc(dim*sizeof(float));
    filtro[i] = *filter_vector(out, N, dim);
    i=dim;
    printf ("Il valore del vettore in uscita e' filtro[%d]=%f \n", i, filtro[i]);
    for (i=2; i<dim; i++) {
        printf ( "filtro[%d]=%f \n", i, filtro[i]);
        }
        max= calcola_max (out, dim);
        min =calcola_min (out, dim);
        printf ("Il valore massimo del vettore in uscita e' %f \n", max);
        printf ("Il valore minimo del vettore in uscita e' %f \n", min);
        count = conteggio (out, dim);
        printf ( "Gli elementi adiacenti il cui valore è maggiore di 16000 sono %d \n", count);
        
        
    
    system("pause");
}


/* Funzione riempi vettore */
void riempi_vettore (float *v, int size) {
      int i;
      for (i=0; i<size; i++) {
          v[i]= rand()/(1.0*RAND_MAX)*100; 
          }
      
      
      }
/* Funzione dimensione vettore */

int dimensione_vettore (float *in_vector, int size) {
    int i, k;
    k=0;
    for (i=2; i<size; i++) {
        if (in_vector[i]+0.2*in_vector[i-1]+0.03*in_vector[i-2]<32000) 
        k++;
        }
    
}

float * filter_vector(float * in_vector, int in_vector_size, int *out_vector_size) {
      int i;
      float *out_vector;
      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[i]=in_vector[i]+0.2*in_vector[i-1]+0.03*in_vector[i-2];
                  }                                                
          
          }
      return out_vector;
      }
/*Funzione massimo */
float calcola_max(float * v, int size)
{
      float max;
      int i;
      max = v[0];
      for (i = 1; i < size; i++) {
          if (v[i] > max) max = v[i];
      }
      return max;
}

float calcola_min(float * v, int size)
{
      float min;
      int i;
      min = v[0];
      for (i = 1; i < size; i++) {
          if (v[i] < min) min = v[i];
      }
      return min;
}

/* Conto quante volte si presentano due elementi adiacenti il cui valore è maggiore di 16000 */

int conteggio ( float *v, int size) {
    int i, k;
    k=0;
    for (i=2; i< size; i++) {
        if (( v[i]>16000)&&(v[i+1]>16000)) {
    k++ ;
                                    }
                           }
                   return k;
                   }

vict85
Tanto per incominciare dovresti vedere che errori ti dà il compilatore.

La riga
filtro[i] = *filter_vector(out, N, dim);
lascia molto perplesso sia me che il compilatore per esempio. Che volevi fare in questa riga esattamente?

Dopo di che filter_vector non crea nessuna memoria e carica out invece che a. Tra l'altro out neanche lo hai inizializzato.

Secondo me dovresti fermarti un secondo, dividere il problema in parti e scrivere una riga per volta ma cercando di capire che cosa fa ogni riga.

C'é anche la funzione dimensione_vettore che non ritorna il valore...

bad.alex
vict85, ti ringrazio. Onestamente, non so più neanche io cosa volessi fare in quella riga, come nel resto del programma -.-'
Sto entrando in confusione con quella funzione filtro. Avete provato a spiegarmi ma ancora non ho capito cosa devo scrivere nel testo. E il programma non parte ( sino al riempimento del vettore con numeri casuali ci arrivo, per il resto ancora no...).
Gli errori segnalati dal compilatore sono "In function main" e "Warning, passing arg 3 of filter vector makes pointer from integer without a cast".
Avrei bisogno di semplici spiegazioni , con qualche esempio, possibilmente affine ma non per forza su questo testo di problema. Su internet ho cercato di tutto ma niente riesce a farmi capire in maniera chiara lo svolgimento di questo esercizio. Sapere il perchè si svolge in questo modo già sarebbe un passo avanti. Ma questo non sempre te lo spiegano i prof nè durante le lezioni nè durante l'orario di ricevimento. Se qualcuno di voi, appassionato e con un pò di pazienza, potesse venirmi incontro, sarebbe già qualcosa. Sto provando a seguire i vostri suggerimenti, ma il disordine ancora regna sovrano. Ho studiato anche sul Deitel e sinora alcuni programmi presenti lì li ho svolti e correttamente. Non capisco perchè con esercizi del genere io entri nel panico...

bad.alex
"claudio86":
Innanzitutto i deve partire da 2, non da 0, perché ad ogni iterazione controlli anche in_vector[i-2]. E deve arrivare ad in_vector_size, non in_vector (che ha poco senso).

Si, mi sono reso conto dell'errore, subito dopo. Già corretto.

"claudio86":
La dimensione di out_vector viene calcolata dentro la funzione filter_vector, che la comunica al chiamante scrivendola all'indirizzo di out_vector_size.

Se fosse possibile, potreste scrivermi voi questa funzione, inserendo qualche commento durante i vari passaggi?
E' il punto che non riesco a svolgere...

"claudio86":

- Crei un nuovo array di N elementi.
- Scorri l'array iniziale, inserendo nel secondo array tutti gli elementi che soddisfano la condizione (e contandoli = K).
- Chiami realloc sul secondo array, ridimensionandolo a K elementi.

Alla fine assegni *out_vector_size = K e restituisci il secondo array.

Ho provato svolgere questo secondo punto come da te suggerito però con pochi esiti positivi in quanto non si avvia il programma. ho pubblicato ( in parte perchè ho provato a rifare di nuovo tutto da capo) lo svolgimento ma vorrei sapere oltre gli errori anche le eventuali correzioni.

vict85
Fartelo mi pare poco educativo, Claudio ti ha dato già una falsariga. Prova a scrivere punto per punto il codice corrispondente e poi lo riunisci tutto.

bad.alex
Vict85, non si tratta di "farmelo", si tratta quanto meno se vi fosse possibile di illustrarmi i passaggi magari spiegandomi il perché si faccia questo piuttosto che altro.
Nonostante i suggerimenti fornitimi dall'utente, il programma non viene visualizzato correttamente. I valori del nuovo vettore sono tutti uguali al valore nullo. Questo perché non so come procedere. Su internet sto cercando qualche esempio analogo ma senza successo. Non chiedo la soluzione ma confido nella disponibilità vostra, per quanto possibile, di farmi conoscere il procedimento per questa tipologia di esercizi. Non voglio essere lavativo, tutt'altro!
Ho provato a svolgerlo e ho apportato qualche modifica al programma ( come da suggerimento). Eppure...qualcosa non torna, perché il programma non viene mandato in esecuzione ( e soprattutto non vengono segnalati errori).
Ad ogni modo, i suggerimenti sono stati preziosi. Per come possibile, anche se con parecchie difficoltà, riproverò a seguirli.

vict85
Indicativamente, come ha detto Claudio, hai due modi. Il più semplice per certi versi è quello di calcolarti all'inizio della funzione la dimensione:

*out_vector_size = dimensione_vettore(in_vector, in_vector_size);
(ricordati di mettere il return dentro dimensione_vettore però)

dopo di che generi l'array
float *out_vector =(float*)malloc((*out_vector_size) * sizeof(float));


e infine inserisci gli elementi
for(int i=2; i<in_vector_size; i++)
    {
        int const value = in_vector[i] + 0.2*in_vector[i-1] + 0.03*in_vector[i-2];
        if ( value < 32000)
        {
            out_vector[i] = value;
        }
    }


per poi far ritornare l'array
return out_vector;

(che ti devi ricordare di deallocare alla fine del main() ).

Che poi è quello che ti ha detto Claudio :roll:

Il problema del tuo codice è anche e soprattutto nel main e nella chiamata della funzione in cui sembra tu non abbia proprio chiaro quali siano gli input e output della funzione.

bad.alex
Ti ringrazio Vict.
RIporto lo sovlgimento, tenendo conto dei vostri suggerimenti ( il programma però non viene compilato in quanto sono presenti alcuni errori....e credo anche nei parametri delle funzioni che riguardano il nuovo vettore e nell'utilizzo dei puntatori):
#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; 


a = malloc(100*sizeof(float));
printf( "Riempi vettore con valori casuali \n");
riempi_vettore(a,100);
printf("Stampa vettore\n");
stampa_vettore (a, 100);
printf( "Il nuovo vettore e':\n");
out = *filter_vector (a, 100, 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]);
                              }
MAX(a , 100 , out_size);
MIN(a , 100 , out_size);
  
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;
      int         i , value ;
      
      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; i++) {
          if (out[i] > max) max = out[i];
      }
      printf( "Il valore massimo del nuovo vettore è:\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; i++) {
          if (out[i] < min) min = out[i];
      }
      printf( "Il valore minimo del nuovo vettore è:\n", min);
      
return min;
}      


Gli errori che mi dà sono di incompatible types in assignment , in function main, in function filter_vector e un warning in passing arg 3 of filter vector makes pointer from integer without a cast e i calcola_max e min....

claudio862
Questi sono gli errori che riporta il compilatore:

a.c:21:3: error: array type 'float [100]' is not assignable
a = malloc(100*sizeof(float));
~ ^

Non puoi assegnare un valore ad un array.
Tu hai dichiarato float a[N] (con N=100), quindi a è un array statico di 100 elementi float. Non ti serve (e non puoi) assegnargli l'indirizzo di un blocco di memoria dinamico (restituito da malloc).

a.c:27:31: error: incompatible integer to pointer conversion passing 'int' to parameter of type 'int *'; take the address with & [-Werror,-Wint-conversion]
out = *filter_vector (a, 100, out_size);
                              ^~~~~~~~
                              &
a.c:10:67: note: passing argument to parameter 'out_vector_size' here
float *filter_vector( float *in_vector, int in_vector_size, int * out_vector_size);
                                                                  ^

Il terzo parametro di filter_vector è un puntatore a int, non puoi passargli un int. Devi passargli il suo indirizzo con & out_size.

a.c:27:5: error: assigning to 'float *' from incompatible type 'float'; remove *
out = *filter_vector (a, 100, out_size);
    ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

out è un puntatore a float, filter_vector restituisce un puntatore a float. Devi semplicemente assegnare a out il risultato di filter_float, senza dereferenziarlo (togli il *).

a.c:34:1: warning: implicit declaration of function 'MAX' is invalid in C99 [-Wimplicit-function-declaration]
MAX(a , 100 , out_size);
^
a.c:35:1: warning: implicit declaration of function 'MIN' is invalid in C99 [-Wimplicit-function-declaration]
MIN(a , 100 , out_size);
^

Chiami queste due funzioni che non sono definite né dichiarate da nessuna parte. Cosa dovrebbero fare?

a.c:93:44: error: incompatible integer to pointer conversion passing 'int' to parameter of type 'int *'; take the address with & [-Werror,-Wint-conversion]
      out = *filter_vector (out_v, size_v, out_size);
                                           ^~~~~~~~
                                           &
a.c:63:67: note: passing argument to parameter 'out_vector_size' here
float *filter_vector (float *in_vector, int in_vector_size, int * out_vector_size) {
                                                                  ^
a.c:93:11: error: assigning to 'float *' from incompatible type 'float'; remove *
      out = *filter_vector (out_v, size_v, out_size);
          ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Stesso discorso di prima, passa l'indirizzo di out_size e togli il *.

a.c:98:60: warning: data argument not used by format string [-Wformat-extra-args]
      printf( "Il valore massimo del nuovo vettore è:\n", max);
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  ^

Manca un marcatore %f nella stringa passata a printf.

a.c:108:7: warning: implicit declaration of function 'out_filter_vector' is invalid in C99 [-Wimplicit-function-declaration]
      out_filter_vector (out_v, size_v, out_size);
      ^

Qui probabilmente volevi fare out = filter_vector...

a.c:113:59: warning: data argument not used by format string [-Wformat-extra-args]
      printf( "Il valore minimo del nuovo vettore è:\n", min);
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  ^

Come sopra, manca %f.

claudio862
"vict85":
[...]
e infine inserisci gli elementi
for(int i=2; i<in_vector_size; i++)
    {
        int const value = in_vector[i] + 0.2*in_vector[i-1] + 0.03*in_vector[i-2];
        if ( value < 32000)
        {
            out_vector[i] = value;
        }
    }

[...]


Qui c'è un errore. non puoi assegnare value ad out_vector[ i], perché i scorre sugli indici dell'array in ingresso, mentre l'array in uscita è (potenzialmente) più corto.

Devi invece "appendere" value ad out_vector. Cioè devi tenere traccia di quale posizione hai scritto l'ultima volta. Qualcosa del genere:
int j = 0;
for(int i=2; i<in_vector_size; i++)
    {
        int const value = in_vector[i] + 0.2*in_vector[i-1] + 0.03*in_vector[i-2];
        if ( value < 32000)
        {
            out_vector[j] = value;
            j++;
        }
    }




Infine, nella funzione filter_vector, tu assegni a out_vector_size la dimensione del nuovo vettore, ma è sbagliato. Devi assegnarla ad *out_vector_size. Il primo ciclo va quindi riscritto così:

      *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;
                                                                       }
                                                                  }

Perché out_vector_size è un indirizzo, il valore puntato si ottiene con l'operatore *. Nella riga successiva usi appunto correttamente *out_vector_size, ma nel ciclo sovrascrivevi il valore dell'indirizzo con un valore senza senso.

bad.alex
Ti ringrazio Claudio. Ho commesso la svista del marcatore %f sia in calcola_max e min ( come mi hai fatto giustamente notare) per non parlare di quel max e min non dichiarato ( avevo dichiarato la funzione calcola...).
Ti ringrazio per il filter_vector, per avermi fatto notare( perchè avrei ricommesso l'errore dell'attribuire il valore int al puntatore) l'errore sul puntatore filter e sull'indirizzo out_size.
Tuttavia, il compilatore continua a darmi messaggio di errore in a = malloc(N*sizeof(float)).
Inoltre, volevo chiederti quale programma/compilatore utilizzassi. Gli errori al momento della compilazione che ti segnala mi tornerebbero parecchio utili ora come ora ( col dev c++ riporta soltanto la riga e il tipo di errore, ma non l'eventuale correzione).
Grazie ancora per l'aiuto.

vict85
"claudio86":
[quote="vict85"][...]
e infine inserisci gli elementi
for(int i=2; i<in_vector_size; i++)
    {
        int const value = in_vector[i] + 0.2*in_vector[i-1] + 0.03*in_vector[i-2];
        if ( value < 32000)
        {
            out_vector[i] = value;
        }
    }

[...]


Qui c'è un errore. non puoi assegnare value ad out_vector[ i], perché i scorre sugli indici dell'array in ingresso, mentre l'array in uscita è (potenzialmente) più corto.

Devi invece "appendere" value ad out_vector. Cioè devi tenere traccia di quale posizione hai scritto l'ultima volta. Qualcosa del genere:
int j = 0;
for(int i=2; i<in_vector_size; i++)
    {
        int const value = in_vector[i] + 0.2*in_vector[i-1] + 0.03*in_vector[i-2];
        if ( value < 32000)
        {
            out_vector[j] = value;
            j++;
        }
    }
[/quote]

:oops: Hai ragione :p Come sempre scrivere di getto e senza compilare non paga :D.


"claudio86":
Infine, nella funzione filter_vector, tu assegni a out_vector_size la dimensione del nuovo vettore, ma è sbagliato. Devi assegnarla ad *out_vector_size.


Questo però io lo avevo messo corretto :roll: avrei dovuto evidenziarlo di più. Anche se sinceramente avrei messo un reference invece che un puntatore e mi sarei tolto la briga di dover mettere l'asterisco tutte le volte.

claudio862
"bad.alex":
Tuttavia, il compilatore continua a darmi messaggio di errore in a = malloc(N*sizeof(float)).

È il primo commento nel mio post di prima. Togli semplicemente quella riga.

"bad.alex":
Inoltre, volevo chiederti quale programma/compilatore utilizzassi. Gli errori al momento della compilazione che ti segnala mi tornerebbero parecchio utili ora come ora ( col dev c++ riporta soltanto la riga e il tipo di errore, ma non l'eventuale correzione).

Dev C++ dovresti buttarlo. Lascio agli altri consigliarti un'alternativa (di solito si va per CodeBlocks o direttamente con Visual Studio Express).
Il compilatore che uso io è Clang, qui trovi le istruzioni su come installarlo su Windows.

"vict85":
Questo però io lo avevo messo corretto :roll: avrei dovuto evidenziarlo di più. Anche se sinceramente avrei messo un reference invece che un puntatore e mi sarei tolto la briga di dover mettere l'asterisco tutte le volte.

Ed avresti ottenuto altri errori, dato che in C i riferimenti non esistono :P

claudio862
Altri tre problemi:
- Hai definito una macro N=100, ma la usi solo nella definizione di a, mentre alle righe 23, 25 e 27 usi direttamente il numero 100. Se cambi il valore di N il programma non funziona più. Usa N anche in quelle righe.
- Nella funzione filter_vector() hai dichiarato value come int, mentre dovrebbe essere un float.
- L'array restituito da filter_vector() è stato allocato con malloc(), quindi va deallocato chiamando free().

vict85
"claudio86":
Ed avresti ottenuto altri errori, dato che in C i riferimenti non esistono :P


Non ho detto che avrei continuato ad usare il C ;-)

Se invece avessi continuato ad usare il C avrei probabilmente fatto ritornare la dimensione della variabile e caricato invece il puntatore con un puntatore a puntatore. Per puri fatti estetici ovviamente :D

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