risolto:Come resettare una struct

Ciao a tutti, mi trovo con un dilemma; ho una struct con variabili di vario formato

struct memo{unsigned long evento_start[17];    
            unsigned long evento_stop[17];        
            unsigned long evento_durata[17];          
            unsigned long durata_programma; 
            unsigned  int cadenza_incrementi[6]; 
             unsigned int lettura_pot[8];  
             unsigned long evento[5];  
             byte traccia[5];                            
};
struct memo memoria;

ad un certo punto del mio sketch decido di azzerare tutti i valori delle variabili.
esiste un modo rapido ed elegante di farlo o devo farlo variabile per variabile??
Io ho fatto così:

for (byte i=0;i<17;i++){
                                    memoria.evento_start[i]=0; 
                                    memoria.evento_stop[i]=0;        
                                    memoria.evento_durata[i]=0;
                                   }                   
             memoria.durata_programma=0;   
           for (byte i=0;i<5;i++){
             memoria.evento[i]=0xffff;  
             memoria.traccia[i]=0;                         
           }

Grazie.

Da una breve ricerca "c reset struct" su google sembra che

static const struct memo EmptyStruct;
memoria = EmptyStruct;

Sia una strada percorribile o anche:

memset(&memoria, 0, sizeof memoria);

Ma non ho provato nessuna delle due :slight_smile:

... mi piace più la seconda, che, per altro, ho usato varie volte anche io :smiley:

Guglielmo

Ma la seconda non fallisce su cose tipo questa che segue?

...
memoria.evento[i]=0xffff;
...

perchè mette tutto a zero mentre qui è inizializzata a tutti 1.

Se una struct non ha elemento con valori di default preimpostati, ok, altrimenti...

Maurizio

maubarzi:
Ma la seconda non fallisce su cose tipo questa che segue?
perchè mette tutto a zero mentre qui è inizializzata a tutti 1.

Se una struct non ha elemento con valori di default preimpostati, ok, altrimenti...
Maurizio

Ma la prima, come fai ? In C standard non conosco valori di default per una struct (forse in C++ si ? )

maubarzi:
Se una struct non ha elemento con valori di default preimpostati, ok, altrimenti...

Maurizio

Già :wink:

nid69ita:
Ma la prima, come fai ? In C standard non conosco valori di default per una struct (forse in C++ si ? )

... credo che la soluzione sia nella parolina "static" ... le variabili statiche vengono, di base, tutte inizializzate a zero dal compilatore.

Resta comunque vero il problema che entrambe le soluzioni inizializzano a 0x00, mente effettivamente sembrerebbe esserci un campo che va inizializzato a 0xFFFF ...

... va beh ... è cosa che potrà fare dopo il memset() con una normale assegnazione :grin: :grin: :grin:

Guglielmo

Ma @maubarzi, da come scrive, mi sembra far intendere che la prima funzioni anche con valori di inizializzazione diversi da 0, ma usando valori di default. Che non ricordo ci siano in C standard, magari in C++ ci sono ?

Da breve ricerca al primo link trovato, si apre un mondo su valori default per una struct in C/C++ :smiley: :smiley: :smiley:
Almeno 6 diversi suggerimenti per val default, da macro a funzioni a cose specifiche del gcc :grin:
P.S. ma per il C sono "trucchi", nel C++ hanno introdotto valori default link dal C++11

Ho letto male io il post, pensavo che il pezzo che ho evidenziato fosse dentro alla definizione della struct.
Sorry.

Comunque, a parte la mia svista nel caso specifico, il concetto che volevo esprimere è corretto.
Che poi sul C non sia previsto inizializzare un valore nella struct, è un altro problema che taglierebbe eventualmente la testa al toro.
Ma dalla tua breve ricerca parrebbe si possa fare, quindi anche se il mio intervento parte da un post sbagliato, alla fine era comunque pertinente :stuck_out_tongue: ;D

Io le struct ancora non le ho mai usate in modo serio, per cui certi dettagli ancora mi sfuggono.

Ho commentato solo la seconda, perchè mi aveva colpito il totale reset a zero.
Comunque, come dice Guglielmo, un modo semplice per approcciarsi è distinguere in definizione della struct e impostazione dei valori di default da richiamare subito dopo la creazione o il reset.

Maurizio

nid69ita:
...
Almeno 6 diversi suggerimenti per val default, da macro a funzioni a cose specifiche del gcc :grin:

Quel che si dice ll'imbarazzo della scelta ... che vuoi di piu, un lucano ? (o magari una lucana ... :D)

(e comunque, dei tre quarti del contenuto di quel link, ancora non ci ho capito nulla ... troppo poco alcool in circolo, probabilmente ... rimediero' piu avanti :stuck_out_tongue: :D)

E molto banalmente creare una variabile struttura 'vuota' ovvero inizializzata come si deve

E usarla in assegnazione alla variabile da resettare?

Questo non crea frammentazione della memoria, oppure dici di creare la nuova struct locale e opportunamente inizializzata e poi copiarne il contenuto di memoria sulla memoria allocata da quella originaria?

Maurizio

Standardoil:
E molto banalmente creare una variabile struttura 'vuota' ovvero inizializzata come si deve ...

Beh, allora tanto vale inizializzare come si deve la struct creata ... sempre se è una sola ... se sono più strutture identiche, allora si, può essere una buona strada, una inizializzata che viene copiata nelle varie strutture ... ::slight_smile:

Guglielmo

Bah, se poi vogliamo fare le cose complicate, allora basta trasformare la struct in class e definire quindi il costruttore, per cui si crea ex novo quando serve. :wink:

Ma, battute a parte, io voto sicuramente per la soluzione più pratica:

memset(&memoria, 0, sizeof memoria);

Una sola istruzione, che fa tutto.
Se poi ci sono solo ALCUNI valori di default diversi da zero, basta aggiungerli dopo la memset().

Se TUTTI o MOLTI dei campi vanno inizializzati con qualcosa di diverso, allora o si fa una funzione resetstruct() che fa questo (soluzione "banale"), oppure si definisce una costante come byte array (es. "const byte memoria0[] = { ...tutti i byte...}") con la sequenza di byte che rappresenta tutti i valori iniziali quindi con una semplice

memcpy(memoria, memoria0, sizeof memoria0);

si rimette tutto a posto.
L'unica accortezza durante lo sviluppo, è di mantenere sempre allineate le dimensioni di memoria0 con la struttura.

Grazie a tutti per i suggerimenti; credo che userò la

memset(&memoria, 0, sizeof memoria);

e poi inizializzo la variabile

memoria.evento[i]=0xffff;

Un'istruzione e mi risolve davvero il problema.
Grazie delle spiegazioni.

Condivido quanto detto da @docdoc. Aggiungo tanto per ricordarvelo che con arduino IDE il compilatore è avr-g++ e anche il linker è specifico per c++, per cui per struct ecc si deve fare riferimento al manuale C++.

Se volete usare C serve usare avr-gcc cosa che con arduino non è possibile fare. mplabx permette di selezionare sia il compilatore C o C++ e anche tutte le flag.

In C++ il manuale riguardo alle struct dice che sono equivalenti alle classi ma queste di default sono private mentre le struct sono sempre public.

Mentre riguardo al ctor di struct non ricordo, non ho il manuale con me.

Ciao.

Siamo d'accordo che la cosa più pratica è memset() anche perché l'utente che pone la domanda ha diversi membri array di dimensioni notevoli.

Visto però che siamo in C++ e siamo curiosi, provato e quel discorso di una static vuota con dei default funziona:

struct prova
{ int uno[3]={1,1,1};
  int due[4]={2,2,2,2};
};

struct prova y;             // oppure prova y;
static const struct prova nullo;

void setup()
{ Serial.begin(9600);
  Serial.print("y.uno="); Serial.println(y.uno[2]);    // stampa 1
  y.uno[2]=33;
  Serial.print("y.uno="); Serial.println(y.uno[2]);   // stampa 33
  y=nullo;
  Serial.print("y.uno="); Serial.println(y.uno[2]);  // stampa 1
}

void loop(){}

E ancora x curiosità, nel C++ se per la struct si crea un costruttore, è possibile usare la lista di inizializzazione:

struct prova
{ int uno;
  int due;
  prova(int a=1,int b=2) {uno=a; due=b; };
};

struct prova y{33,44};

Di tutte queste "novità" del C++ rispetto al C me ne ricordavo solo alcune, ad esempio in C++ non è più obbligatorio usare la parola struct nella dichiarazione

P.S. la versione con la static: occupa codice 1932 byte, dati 202
mentre la versione con solo memset occupa codice 1894 e dati 198.
Quindi quel static const struct occupa e anche il codice è maggiore. Più snella la memset()