Ciao a tutti, c'è qualcuno di buona volontà che mi potrebbe spiegare questa riga di codice, o meglio, ho capito che pone la variabile i a 0 poi dice, finchè i è minore di 255.....ecco, l'ultima parte non l'ho capita.
Gli operatori di incremento e decremento i++ i-- , dovrebbero corrispondere a un codice macchina più semplice "mi pare un unica istruzione", per cui sono da preferire.
Nei cicli for() a volte capita di dover incrementare di valori superiori all'unità, allora in quel caso si usa +=.
In definitiva se devi incrementare di uno è meglio usare i++ , se devi incrementare di valori superiori allora
Era una cosa che avevo letto da qualche parte! Dove diceva che alcune istruzioni del C venivano tradotte in un unica istruzione in assembly, e faceva proprio l'esempio degli operatori di incremento
Ma non conosco l'assembly e non ho mai visionato il codice assembly di un codice C...
torn24:
Era una cosa che avevo letto da qualche parte! Dove diceva che alcune istruzioni del C venivano tradotte in un unica istruzione in assembly ...
Vero, ma devi sempre considerare le altre istruzioni che servono a recuperare la variabile e poi a salvarla, quindi, un banale i++ o i+=1 (ma rimane valido per qualsiasi valore), ottimizzando al massimo, con una variabile di tipo intero non segnata comporta comunque cinque istruzioni assembler ...
lds r24, 0x0100 // recupera il primo byte dell'intero e lo mette in r24
lds r25, 0x0101 // recupera il secondo byte dell'intero e lo mette in r25
adiw r24, 0x01 // somma il valore 1 alla word che ora si trova in r24 e r25
sts 0x0101, r25 // salva il secondo byte da r25
sts 0x0100, r24 // salva il primo byte da r24
... come vedi, l'incremento (o la somma di un valore) è effettivamente fatto con una singola istruzione macchina, ma intorno c'è dell'altro e alla fine, comunque, almeno 5 istruzioni devi fare.
>SukkoPera: il caso riportato NON è relativo ad un ciclo for, ma alle due operazioni indicate. Quanto all'ampiezza dell'indice è l'utente che lo impone dichiarando la variabile del for, NON il compilatore ... se gli dici che i è int e poi vai solo da 0 a 255 userà sempre e comunque 2 bytes del int che hai dichiarato e non 1 ... :
Sì, ma in un caso come quello proposto, in cui 0 <= i <= 255, e supponendo che i non venga modificato all'interno del loop, non vedo perché un compilatore non possa rendersi conto che basta un singolo byte e ottimizzare!
>Sukkopera: non ottimizza, rispetta le scelte dell'utente ...
Preso un programmino stupido come questo:
volatile int a;
int i;
void setup() __attribute__((optimize("-O3")));
void setup() {
// put your setup code here, to run once:
for(i=0; i<255;i++) {
a += i;
}
}
void loop() {
// put your main code here, to run repeatedly:
}
in cui ho:
forzato l'aggiornamneto di 'a' dichiarandola 'volatile' (altrimenti il compilatore che è furbo, vendendo che non era utilizzato nulla, buttava tutto)
per il setup() ho richiesto il massimo dell'ottimizzazione per la velocità (-O3)
... dove, come puoi ben vedere, usa per la variabile 'i' intera i due registri r24 e r25 che inizializza a zero, effettua una add word di 1 sul numero che sta a partire da r24 e effettua il compare con il 255.
Ovvio che SI ...
... se difatti dichiari la variabile 'a' di un byte e lasci 'i' come int, l'assembler equivalente, nel for, è ottimizzato ad utilizzare solo il byte meno significativo dell'int (che comunque è e resta un int) che gli basta e gli avanza
Insomma ... dipende molto dal programma, anche se tu vai solo fino a 255, ma coinvolgi nelle operazioni qualche cosa di più grande di un byte, lui, pur sapendo che arriva sino a 255, utilizza tutto l'int, se invece coinvolgi un byte, allora usa solo quello che serve
SukkoPera:
Sì, ma in un caso come quello proposto, in cui 0 <= i <= 255, e supponendo che i non venga modificato all'interno del loop, non vedo perché un compilatore non possa rendersi conto che basta un singolo byte e ottimizzare!
Io parlo adesso senza aver avuto occasione di controllare la documentazione
Però credo che il compilatore se ottimizzasse, in particolare il programma del pst 11 sbaglierebbe alla grande
Quelle variabili sono extern, per il compilatore potrebbero essere usate in file sorgente non ancora compilati, o peggio in oggetti pre-compilati, e il linker ha (avrebbe) bisogno di trovare una variabile del tipo corretto
Che poi lo IDE di Arduino non ne faccia uso è parrocchia differente.....