Salve, mi dite come funziona sizeof con gli array? Ho fatto delle prove ma dai risultati non ho capto come funziona. In questo sketch mi esce sempre zero, invece dovrebbe dirmi da quanti elementi è formato l'array.
void draw_menu(String disegna_menu[]) {
int num_ele = sizeof(disegna_menu)/sizeof(disegna_menu[0]);
Serial.print(num_ele);
for (int i = 0; i < num_ele; i++) { // per ogni elemento del menù
if (i == riga) { // se è l'elemento selezionato
ucg.setColor(1,0, 0, 255); // sfondo blu
} else { // altrimenti
ucg.setColor(1,0, 0, 0); // sfondo nero
}
ucg.setPrintPos(115 -i*20, 10); // posiziono il cursore sul display
ucg.print(disegna_menu[i]); // stampo il nome dell'elemento
}
}
l'utilizzo di sizeof per contare il numero di elementi in un array funzionerebbe correttamente con quel codice indipendentemente dal tipo di elementi.
il problema qui è che quando passi un array come parametro passi solo il puntatore al primo elemento e la dimensione viene persa. questo è ciò che riguarda il decadimento.
basta aggiungere il conteggio come parametro e usarlo nella funzione
Il problema è che li NON sta passando un "char array", ma, peggio, sta passano un oggetto della classe "String"!
Come ha fatto giustamente notare Datman, per determinare la lunghezza di un oggeto della classe "String" c'è un apposito metodo di detta classe, il metodo length().
@J-M-L: ... ok ... vero, non avevo notato le due parentesi quadre dopo disegna_menu[] ... quindi, lui passa un array di oggetti String e vuole sapere quanti elementi ha tale array ... in tal caso, il solo modo è passare un parametro in più con il numero di elementi.
SÌ
oppure utilizzare un template ma non sono molto favorevole a questa soluzione
se il codice è in esecuzione su un Arduino a 32 bit, potrebbe essere utilizzato un diverso tipo di contenitore (vector, ...) e passato per riferimento e la dimensione non andrebbe persa
Ne avevamo già discusso in passato circa i template, ma non ricordo dove, cercherò. Perché non sei favorevole? c'è qualche side effect che non ho considerato in passato. Io ricordo che era equivalente a passare due argomenti.
se chiami la funzione con - diciamo 10 array di dimensioni diverse, il codice della funzione viene duplicato 10 volte...
C'è un modo per aggirare questo: il template chiama una funzione che prende la dimensione come parametro, quindi ottieni meno duplicazioni di codice, ma se ti preoccupi di scrivere tu stesso quella funzione con il parametro dimensione, puoi semplicemente usarlo direttamente.
Altrimenti, nel caso specifico, basta impostare num_ele con un numero massimo di elementi ammessi.
Forse, poi, c'è anche qualche maniera completamente diversa e più semplice per colorare la riga desiderata...
non funzionerà perché una volta passato l'array alla funzione, non è più un array , è un puntatore all'inizio dell'array. (decadimento del puntatore). Quindi otterrai un errore durante la compilazione perché non puoi ottenere un iteratore (begin) per il puntatore.
Cosa succede però se la lunghezza degli item di menuA è variabile?
Secondo me sarebbe preferibile definire la dimensione dell'array a priori magari con un #define
un Array ha una dimensione fissa, il numero massimo di elementi che può memorizzare è noto. Non può crescere né restringersi.
Se non lo riempi, invece di passare il numero massimo, passi un altro numero che corrisponde al numero effettivo di elementi attivi nell'array. ➜ sei responsabile di non passare un valore maggiore della dimensione dell'array
All'inizio avevo creato questa routine passando due elementi, l'array e il numero degli elementi, mi funzionava. Poi navigando in rete mi sono imbattuto nel comando sizeof e così ho pensato di mandare solo l'array e calcolarmi il numero degli elementi in automatico. La stessa formula, nel corpo del programma mi restituisce il numero degli elementi esatti.
Perché nel corpo del programma stai usando l'array stesso e non un suo puntatore.
Come ti ha già spiegato @J-M-L è un fenomeno noto nel C: se fai una ricerca con le parole chiave "array to pointer decay", troverai molte informazioni al riguardo.
Io invece vorrei suggerire un approccio diverso al tuo problema. Se ho ben capito, l'array dovrà contenere le voci di un menù che con tutta probabilità saranno immutabili nel corso dell'esecuzione del programma.
Io non sono un NO-String a prescindere, ma usare un array di String in questo caso comporta un inutile spreco di SRAM.
Fossi in te userei dei const char* salvando l'array nel program space usando la keyword PROGMEM.