Altra stupida domanda, tanto quanta quella posta sullo switch...
#define mioLed 1
const byte mioLed = 2;
Quale usereste delle due, ma soprattutto per quale motivo (memoria RAM, prestazioni, correttezza di definizione secondo voi o secondo il compilatore)...
NOTA: pongo queste domande perché a volte usiamo entrambi le modalità di definire i pin, ma alcuni (proprio come me) non sanno quello che effettivamente varia all'interno del compilatore nonché dell'mcu... Se fossero uguali non avrebbe senso avere due modi di scrivere diversi... Quindi, qualcuno di buon animo, sarebbe disposto a scambiare due chiacchiere? OT: prevedo già qualcuno che mi indica dove devo andare a leggere...
miky_police:
Altra stupida domanda, tanto quanta quella posta sullo switch...
... e niente eh, non c'è nulla da fare, quando uno è pigro è pigro !
E' cosa di cui si è parlato tante volte sul forum e basta fare una piccola ricerca per trovare vecchie discussioni, come QUESTA. Alla fine del thread, la risposta di Astrobeed, è esauriente.
Guglielmo
P.S.: In fondo a tutti i mei post, lo vedi il testo in "firma" ?
Se ho capito bene per singole variabili sono uguali. Solo che #define é un "cerca e sostituisci", quindi non crea la variabile (può anche essere usato per creare finte funzioni o accorciare pezzi fi codice ripetuti) mentre const la crea, e per questo puoi farne array, se fosse più comodo. Personalmente const po uso solo in caso di array, per singole variabili uso #define
Chiaramente quando dico " variabili" intendo non modificabili
@silente, per me la differenza più grande è che una #define per una costante NON ne definisce il tipo.
Ovvero se io creo #define MIONUM 10 non ho detto se quel 10 è int, long o altro.
Invece una const comunque vuole il tipo. E quindi il compilatore non "interpreta" ma del tipo del dato lo hai informato tu.
No, fermi, const alloca memoria
Che poi il compilatore non ti lascia più modificare, li dove la hai "const"....atata
Ma magari in altri moduli, sì
Ovvero una variabile può essere const in un modulo, in una specifica funzione, ma non in un'altra
Rimangono variabili, che possono essere dichiarate extern in altri moduli, che possiedono un indirizzo e che possono essere passate per riferimento in C++ (questo non sono sicuro, non programmo in C++)
e aggiungo, passo ad una funzione l'indirizzo di una const, la funzione lo tratta come un puntatore a variabile, ecco modificata una const senza nemmeno doverla dichiarare extern in un altro modulo
Oltre alla lettura del link di Guglielmo, intanto c'è la logica, ossia se io ho una #define VALORE 584
quel simbolo (VALORE) il compilatore lo sostituisce in tutto il codice quando compila.
Per cui basta fare qualche prova ad esempio:
#define VALORE 584
void setup() {
int p = VALORE;
p += VALORE;
Serial.println(VALORE);
}
equivale a:
void setup() {
int p = 584;
p += 584;
Serial.println(584);
}
Entrambi (Arduino UNO) occupano esattamente 1600 byte per il programma e 188 byte di RAM.
Usare la const ossia:
const int VALORE = 584;
void setup() {
int p = VALORE;
p += VALORE;
Serial.println(VALORE);
}
porta sempre a 1600 byte di programma e 188 byte di RAM.
Si può "risparmiare" invece qualcosa se il valore ad esempio fosse un byte:
const byte VALORE = 84;
void setup() {
int p = VALORE;
p += VALORE;
Serial.println(VALORE);
}
che porta il programma a 1416 byte e sempre 188 di RAM.
In sostanza quindi non c'è quasi differenza (anche se io preferisco in genere le #define perché per convenzione i simboli sono in maiuscolo e li distinguo così dalle variabili normali).
gpb01:
... lo hai letto il thread che ho linkato al mio post #1 ? ... mi sembra di no ... :
Guglielmo
invece si, letto. Anzi già letto in precedenza
In cosa contrasta con quello che ho detto io?
Forse che non puoi passare l'indirizzo di una const?
Forse che non puoi avere un puntatore a const?
Forse che non puoi eguagliare un puntatore a variabile all'indirizzo di una const?
Tutte queste cose non si fanno con le #define
nid69ita: @silente, per me la differenza più grande è che una #define per una costante NON ne definisce il tipo.
Ovvero se io creo #define MIONUM 10 non ho detto se quel 10 è int, long o altro.
Invece una const comunque vuole il tipo. E quindi il compilatore non "interpreta" ma del tipo del dato lo hai informato tu.
Questo è il punto principale!
Inoltre, una constin teoria alloca memoria, ma un compilatore un po' sveglio è in grado di evitarlo facendo la stessa sostituzione che farebbe con una #define. Da qualche parte gpb aveva anche fatto un test di disassembly per provare questo.
In sostanza: meglio una const ovunque possibile, almeno eventuali errori di tipo sono subito beccati dal compilatore. Dove non è possibile, si va di #define.
Un ultimo dettaglio: l'uso ad oltranza di #define è tipico del C, perché non è possibile fare questo:
const int N = 10;
char str[N] = "ciao";
... in quanto gli array devono avere una dimensione fissa e nota a tempo di compilazione (e const significa più "a sola lettura" che "costante"). In C++, invece, la cosa è perfettamente legale, per cui si assiste ad utilizzi di #define più limitati. In teoria, il C++ prevede anche l'uso delle funzioni inline al posto delle macro (cosa poi introdotta anche in C99, mi pare), proprio per eliminare il più possibile i #define, che spesso sono causa di errori e/o incasinamenti generali.
In realtà, se nella #define tu specifichi il tipo (invece che lasciare int di default), ecco che NON risparmi un bel nulla e le due cose tornano equivalenti:
#define VALORE (byte)84
void setup() {
int p = VALORE;
p += VALORE;
Serial.println(VALORE);
}
... ti darà la stessa occupazione del tuo "const byte VALORE = 84;"
... perciò, dagli esperimenti di docdoc al #8 e da quanto detto da SukkoPera al #10:
"Inoltre, una const in teoria alloca memoria, ma un compilatore un po' sveglio è in grado di evitarlo facendo la stessa sostituzione che farebbe con una #define."
sembra che, senza offesa, l'IDE non sia "un po' sveglio"...
Datman:
sembra che, senza offesa, l'IDE non sia "un po' sveglio"...
No, sei TU che stai sbagliando ... 84 così senz'altra specifica è un "int" (che è il tipo di default se non si specifica nulla), mentre nella tua "const" tu per 84 specifichi chiaramente che vuoi un byte e allora ... devi specificarlo anche nella #define.
docdoc:
In sostanza quindi non c'è quasi differenza (anche se io preferisco in genere le #define perché per convenzione i simboli sono in maiuscolo e li distinguo così dalle variabili normali).
In verità il maiuscolo si tende ad usare per le costanti in generale, indipendentemente dal fatto che siano #define o const.
Ritenta sarai più fortunato -> Nessun warning
comunque perchè undefined behavior? non c'è nessuna ambiguità in quello che ho scritto
modificare una variabile puntata da un puntatore valido NON è sbagliato.....
gpb01:
In realtà, se nella #define tu specifichi il tipo (invece che lasciare int di default), ecco che NON risparmi un bel nulla e le due cose tornano equivalenti:
#define VALORE (byte)84
void setup() {
int p = VALORE;
p += VALORE;
Serial.println(VALORE);
}
... ti darà la stessa occupazione del tuo "const byte VALORE = 84;" :D
Guglielmo
Diavolaccio !!
P.S. Che brutto però un cast in un define (non mi piace molto)
Ricordiamo poi quello che disse (giustamente) @astro, non è detto che tutti i compilatori, dato gli esempi fatti con la const, la trattino alla pari di un define; ovvero non è detto sia portabile.