Ciclo for solo con indice int

Sapevate che il ciclo For accetta per gli indici solo variabili (e conseguentemente valori) di tipo int?
Io no. L'ho scoperto stasera quando ho provato a fare un ciclo fino a 500.000 mettendo un unsigned long e non partiva neanche il ciclo For.... eseguiva subito l'istruzione successiva. Se invece cercavo di usare un unsigned int e mettevo come valore massimo 500.000 il codice si compilava ma l'esecuzione arrivava solo a 65535 (il max di un int semplice).

unsigned long i;
for (i=0; i<500000;i++) {
  ...
}

Non va.

unsigned int i;
for (i=0; i<500000;i++) {
  ...
}

Si ferma a 65535

scusa ma gli unsigned int arrivano proprio fino a 65535 e gli int da -32768 a 32767, quindi almeno il secondo funzionamento è giusto.

Mentre per il primo, non saprei, se provi col formato uint32_t che succede? uguale?

Sul secondo non ci piove sul funzionamento anche se il parser non controlla una cippa dato che accetta 500000 come test sull'i :wink:

Sul primo mi aspettavo che andasse dato che lo compilava anch'esso senza errori.... mah...
Ma nel C/C++ qual è il tipo di dato per l'indice?

EDIT:
anche con uint32_t non funziona...

Eppure a me con byte funziona, l'ho praticamente sempre usato cosi'...

EDIT:
ops... non mi ero accorto che si parlava di limite superiore XD

no, aspetta, a me funziona con unsigned long... va oltre il limite che hai detto... puo' essere che magari hai in qualche modo riempito la memoria? boh...

Ma nel C/C++ qual è il tipo di dato per l'indice?

Mi hai fatto venire questo dubbio, giacche' in C ho praticamente sempre usato int :), cosi' ho preso la bibbia, il kernighan-ritchie, sull'ansi c, e non fa menzione del tipo per l'istruzione for. Anzi, in un esempio viene usato il tipo double per l'indice... In C esiste anche il for infinito [for( ; ; )] che per arduino non esiste :slight_smile:

altra cosa, hai provato anche a fare:

unsigned long i;
unsigned long maxIndex = 500000;
for (i=0; i<maxIndex;i++) {
  ...
}

oppure:

unsigned long i;
for (i=0; i<500000UL;i++) {
  ...
}

?

mi è venuto in mente che il problema che si verifica potrebbe essere dato dal numero che usi per fare il confronto. Però non so come vengono gestiti dal compilatore, quindi magari non ha senso quello che sto dicendo.

@superkulak: con te come si comporta? funziona così...senza "accorgimenti"?

Il primo caso da te esposto non l'ho provato, il secondo sì e non è cambiato nulla.
Secondo me è proprio un limite del ciclo, che accetta solo (unsigned) int.
Vabbè, nulla di che. Avessi bisogno, lo sostituisco con un while. Però è buffo...

si beh, inutile provarlo perchè dovrebbe essere del tutto analogo...molto strano però, non dovrebbe esserci un limite! Se è vero è veramente buffo!

Domani per curiosità provo anch'io!!

void setup() {
  Serial.begin(9600);
}

void loop() {
  for(unsigned long i = 0; i < 4294967295UL; i++){
    Serial.println(i, DEC);
  }
}

continua a contare, se volete domani mattina posto il numero a cui e' arrivato :sleeping:

continua a contare, se volete domani mattina posto il numero a cui e' arrivato smiley-sleep

Strano l'operatore unario ++, dovrebbe aggiungere 1, forse visto che 4294967295UL, allora conta 0.1

Comunque il for ;; c'è nel cores di arduino quindi è supportato dal compilatore, viene usato per la funzione loop.

Ciao.

superkulak:

void setup() {

Serial.begin(9600);
}

void loop() {
  for(unsigned long i = 0; i < 4294967295UL; i++){
    Serial.println(i, DEC);
  }
}




continua a contare, se volete domani mattina posto il numero a cui e' arrivato :sleeping:

E che differenza farebbe dichiarare la variabile dentro o fuori dal ciclo? :cold_sweat:

Il problema non è il compilatore, che è il GCC, è il preprocessore usato da Arduino che si prende troppe libertà rispetto alla sintassi standard del C e non prevede tutti i possibili casi.
Lo sketch allegato usa la definizione standard per un long int e infatti funziona perfettamente, la visualizzazione del conteggio avviene ogni 1000 cicli, altrimenti ci vuole una vita per verificare.

unsigned long int i;

void setup() {
  Serial.begin(115200);
}

void loop() {
  for(i = 0; i < 4294967295; i++){
    if (i%1000 == 0) Serial.println(i, DEC);
  }
}

astrobeed:
Il problema non è il compilatore, che è il GCC, è il preprocessore usato da Arduino

Era ciò che pensavo

    if (i%1000 == 0) Serial.println(i, DEC);

Ci ho pensato mentre ero a letto :roll_eyes:, ma tanto avevo tutta la notte, solo che al risveglio ho riflettuto sul fatto che ho messo il ciclo in loop() e non in setup() e quindi l'avra' ricominciato una o due volte e non posso vedere dove si e' fermato :sweat_smile:, ma ha superato gli 800.000 XD (l'IDE ora non risponde piu'...)

E che differenza farebbe dichiarare la variabile dentro o fuori dal ciclo?

La differenza sta nella possibilita' di leggere la variabile al di fuori del ciclo, tutto qui: se la dichiari nel ciclo, il C++ standard la considera fuori dallo scope quando questo termina.

EDIT:

void setup() {

Serial.begin(115200);
}

Non so come mai, ma ieri ho provato ad usare questo baud rate, ma vedevo solo caratteri a caso nel monitor seriale, qualche idea del perche'?

superkulak:

E che differenza farebbe dichiarare la variabile dentro o fuori dal ciclo?

La differenza sta nella possibilita' di leggere la variabile al di fuori del ciclo, tutto qui: se la dichiari nel ciclo, il C++ standard la considera fuori dallo scope quando questo termina.

No, non intendevo questo: questa è lo spazio di visibilità dei nomi, un concetto che mi è chiarissimo XD
Intendevo ai fini del parsing, se il precompilatore dell'IDE magari la considerava in maniera differente.

void setup() {

Serial.begin(115200);
}



Non so come mai, ma ieri ho provato ad usare questo baud rate, ma vedevo solo caratteri a caso nel monitor seriale, qualche idea del perche'?

Anch'io ho notato che esagerando con la velocità la trasmissione impazzisce.

leo72:
Anch'io ho notato che esagerando con la velocità la trasmissione impazzisce.

L' UART del ATmega é dichiarato fino a 115200 BAUD.
Ciao Uwe

superkulak:
Non so come mai, ma ieri ho provato ad usare questo baud rate, ma vedevo solo caratteri a caso nel monitor seriale, qualche idea del perche'?

Perchè probabilmente ti sei scordato di cambiare il baud rate anche sul monitor seriale, l'ho impostato a 115200 per accelerare al massimo il conteggio, il collo di bottiglia è proprio la velocità con cui comunichi i dati via seriale, se lo fai ad ogni ciclo a 9600 baud ci vogliono oltre 42000 secondi (> 11 ore) per completare il conteggio :slight_smile:

Perchè probabilmente ti sei scordato di cambiare il baud rate anche sul monitor seriale

:fearful: cavoli, hai ragione, il sonno deve aver contribuito :sweat_smile: :grin: