Go Down

Topic: Funzioni che returnano array (Read 894 times) previous topic - next topic

MarioMas

Aug 10, 2011, 02:35 am Last Edit: Aug 10, 2011, 03:00 am by MarioMas Reason: 1
Ho un paio di dubbi in proposito, visto che l' ide di arduino lavora in c++ e in c++ gli array nn sono altro che puntatori al primo elemento è corretto scrivere in questo modo:

funzione che processa un array di bytes e restituisce  un altro array

Code: [Select]
byte* myfunz (byte array []){
 
 byte buffer[sizeof(array)];
   
     ..... un bel po di roba

   return buffer;
}


oppure

Code: [Select]
byte myfunz (byte array []){
 
 byte buffer[sizeof(array)];
   
     ..... un bel po di roba

   return *buffer;
}


o ancora

Code: [Select]
byte myfunz (byte array []){
 
 byte buffer[sizeof(array)];
   
     ..... un bel po di roba

   return buffer;
}


Secondo me la prima ma mi da errore oppure l'ultima ma da sempre errore di conversione; dopo di che

Code: [Select]

void Send (byte query[]){
 byte aa = myfunz(query);
 Serial3.write(aa,sizeof(aa));  
}


pero pure li da errore "invalid conversion from 'byte*' to 'byte'   e  'invalid conversion from 'byte' to 'const uint8_t*' "

mentre se faccio

Code: [Select]

void Send (byte quer[]){
 byte aa = myfunz(quer);
 int num = sizeof(aa);
 Serial3.write(&aa,num);  
}


che nn ha senso perchè mi invierebbe l'indirizzo di aa e nn il valore...........

Visto che l'array e creato all interno della funzione quando essa finisce anche l'array viene distrutto quindi ci si ritrova con nulla puntato!! :(
Non penso tocchi ogni volta lavorare su un buffer esterno oppure si??

Girovagando ho trovato  un po di roba ma nn è applicabile qui.

Quella volta i tizzi che hanno pensato ste robe che hanno bevuto??




astrobeed


Visto che l'array e creato all interno della funzione quando essa finisce anche l'array viene distrutto quindi ci si ritrova con nulla puntato!! :(
Non penso tocchi ogni volta lavorare su un buffer esterno oppure si??


Se devi passare un array tra funzioni, o semplicemente ritornare la relativa elaborazione, questo deve essere dichiarato esternamente alla funzione per poi passargli il relativo puntatore, non serve ritornare il puntatore perché la funzione chiamante ne è già in possesso.
La soluzione migliore, in termini di efficienza del programma, è dichiarare come global gli array che devono essere utilizzati da più funzioni.


leo72

Sì, le variabili globali tolgono tanti grattacapi  8)

PS: "ritornare" è una traduzione di RETURN che suona malissimo :smiley-sweat:
Sarebbe da dire "restituire"  :P

astrobeed


PS: "ritornare" è una traduzione di RETURN che suona malissimo :smiley-sweat:
Sarebbe da dire "restituire"  :P


E' vero che suona male, però nel gergo informatico è prassi usare "ritorna" o "ritornare" invece di "restituire".

MGuruDC

È uno degli argomenti più ostici della programmazione in C... vediamo un po'
Code: [Select]
byte* myfunz (byte array []){
 
  byte buffer[sizeof(array)];
   
      ..... un bel po di roba

    return buffer;
}

Sbagliato, sizeof non restituisce la grandezza dell'array in ingresso, restituisce la grandezza dell puntatore all'array.
"sizeof" è un operatore che viene sostituito in tempo di compilazione, non è una funzione come "count()" del php o il ".length" del javascript.
In C gli array(escludendo le stringhe) non hanno nessun delimitatore,  quindi stabilirne la dimensione è compito del programmatore.
Se dichiari buffer in quel modo non puoi restituirlo... in C tutte le variabili dichiarate in un blocco "{}", vengono distrutte alla fine del blocco.
Il modo corretto per restituire un array è un po' più complicato, ti faccio un esempio:
Code: [Select]
byte* myfunz (byte *array, int size) {
byte *buffer = malloc(siezeof(byte) * size);

memcpy(buffer, array, size);

/* ...operazioni sull'array buffer... */

return buffer;
}

Così facendo allochi l'array nella memoria heap e restituisci un puntatore che dice solo DOVE si trovano i dati, e i dati rimarranno lì finché non li punterai con un puntatore e farai:
Code: [Select]
free(punt);

Non hanno bevuto niente di preoccupante, anzi è un meccanismo geniale che tiene in piedi tutta l'informatica moderna... studia e lo capirai...
Ciao

Linux User #503422 | Linux Machine #414597-8 | Ubuntu User #30132

lesto

approvo in pieno la spiegazione di MGuruDC, ed aggiungo: http://programmazione.html.it/guide/lezione/1105/i-puntatori/
leggiti i 3 capitoli successivi sui puntatori e i 2 successivi sull'allocazione dinamica della memoria (la malloc & co.), benvenuto nel "bello" della programmazione :)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

MarioMas

Grazie dell'ottima spiegazione ragazzi, in 4 ore non avevo trovato nulla di cosi chiaro.

Un altra cosa:

Io uso molti array dinamici nel mio piccolo progettino, c'è una maniera per stabilirne le dimensioni senza troppe macchinazioni?

Ho pensato di inserire un carattere di fine come x i char e andarlo poi a cercare ma mi sembra faccia parte delle machinazioni :)

leo72

Non puoi tenere una semplice variabile contatore che incrementi ogni volta che aggiungi un elemento?

lesto

oppure se proprio vuoi fare il figo, una struttura che contiene puntatore all'array e dimensione. quando cambi la dimensione riallochi anche l'array(il puntatore).
(e già ci avviciniamo alla programmazione ad oggetti)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

MarioMas

Già sto litigando con il c++ va be proverò e poi posto se funzia :)

Non posso usare una variabile esterna perchè in pratica queste funzioni che uso sono sparse in giro a livelli differenti e richiamate su array differenti quindi diventerebbe un casino,
Vada per la struct cosi almeno lo faccio JavaLike, nn si sa mai che ne emerga una nuova libreria x arduino

lesto

se usi il c++ puoi fare una classe che oltre a memorizzare l'array gestisca anche la sua allocazione etc...
cosa che con una struct non verrebbe "pulita" allo stesso modo.

la struct usala se vuoi rimanere nell'ambito C
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

MarioMas

#11
Aug 12, 2011, 02:45 am Last Edit: Aug 12, 2011, 02:51 am by MarioMas Reason: 1
Ho trovato questa classe che sembra funzionare benino

http://www.anyexample.com/programming/cplusplus/cplusplus_dynamic_array_template_class.xml

Per farla andare però bisogna rimuovere
Code: [Select]
if (array == NULL)
throw MEMFAIL;


in 4 posizioni perché il compilatore non accetta le eccezioni, per provare non succede nulla :)

finalmente posso fare

Code: [Select]
Serial.write((byte*)array.getptr(),array.GetSize());

Go Up