Go Down

Topic: Funzioni che returnano array (Read 1 time) 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy