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;
}
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
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++
Almeno 6 diversi suggerimenti per val default, da macro a funzioni a cose specifiche del gcc
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 ;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.
nid69ita:
...
Almeno 6 diversi suggerimenti per val default, da macro a funzioni a cose specifiche del gcc
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 :D)
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?
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 ... :
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.
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.
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.
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()