Corrono entrambi, come è stato sottolineato in altre risposte.
Considera il concatenatore di corde canonico while(*s1++ = *s2++);
una volta s1
e s2
sono stati inizializzati. expr
in questo caso è *s1++ = *s2++
e il corpo del ciclo while è l'istruzione vuota ;
. Ricorda che in C, il valore di un'assegnazione è il valore assegnato, quindi questo potrebbe essere riscritto come
while((*s1++ = *s2++) != 0)
{
}
e hanno lo stesso effetto (con possibili variazioni nelle prestazioni a seconda delle ottimizzazioni eseguite dal compilatore).
Probabilmente la tua confusione deriva dal fatto che if
e while
sono entrambi seguiti da una singola istruzione o da un singolo blocco di istruzioni. Quando si inserisce un terminatore di istruzione punto e virgola dopo la parte condition, diventano semanticamente equivalenti a:
while(expr)
{
}
{
/* do something */
}
e
if(expr)
{
}
{
/* do something */
}
che sono entrambi codici perfettamente validi (puoi avere un blocco vuoto o un blocco senza un'istruzione di controllo di flusso associata) ma probabilmente non fare ciò che vuoi.
Se expr
è costante , che è spesso il caso in cui nessuna variabile costitutiva viene modificata nel ciclo (vuoto), allora il ciclo while salterà il blocco di istruzioni vuoto (se expr
restituisce false) o diventa un ciclo infinito eseguendo l'istruzione vuota (se expr
restituisce true).
Puoi verificarlo dando a expr
un effetto collaterale senza interruzioni, come la registrazione di un messaggio o l'incremento di alcune variabili interne statiche o di stato membro:
while(log_message(), expr);
e osserva che la funzione log_message () viene chiamata ripetutamente.
Supponendo che il tuo codice sia qualcosa del tipo:
int x = 0;
while (x < 1234);
{
x++;
}
/* do more... */
ora dovrebbe essere ovvio il motivo per cui il tuo programma non fa quello che ti aspetti, in quanto quanto sopra è semanticamente equivalente a:
int x = 0;
while (x < 1234)
{
}
{
x++;
}
/* do more... */
Poiché x
non viene mai modificato all'interno del blocco di istruzioni del ciclo while (poiché è vuoto), l'espressione x < 1234
non valuterà mai nulla di diverso da vero, e quindi avrai un ciclo infinito. Se invece l'espressione fosse x != 0
, il blocco di istruzioni vuoto verrà saltato perché la condizione del ciclo while viene valutata come false, si raggiungerà x++
e si concluderà con x == 1
nel punto di /* do more... */
.
Se la condizione era invece qualcosa come ++x < 1234
, allora x
sarebbe semplicemente incrementato ( ++x
valutato), e il blocco di istruzioni vuoto eseguito , finché la condizione non è vera, dopo di che il ciclo while termina e l'esecuzione continua con un singolo passaggio attraverso ciò che intendi fare un certo numero di volte.