Valutazione a corto circuito: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Nessun oggetto della modifica
Riga 164:
<sup>8</sup> I linguaggi [[BASIC]] che hanno supportato le istruzioni CASE lo hanno fatto usando un sistema di valutazione condizionale, invece che tabelle di salto limitate ad etichette (label) fisse.<br>
 
== EsempiUsi comuni ==
 
=== Forma compatta di if/else ===
In uno script di [[Shell (informatica)|shell]]:
test -d /tmp/foo || mkdir /tmp/foo
In questo caso il comando <tt>mkdir /tmp/foo</tt> viene eseguito unicamente se il risultato del primo comando (che verifica l'esistenza della [[directory]] /tmp/foo) è falso, per via della valutazione a corto circuito dell'operatore OR (indicato come <tt>||</tt> nello script). Rappresenta una forma compatta di
if ! test -d /tmp/foo; then mkdir /tmp/foo; fi
 
=== Evitare effetti indesirati del secondo argomento ===
 
Nel [[C (linguaggio)|linguaggio C]]:
 
<source lang=c>
if (denom != 0 && num / denom)
char * p;
{
...
... // assicura che l'espressione num / denom non risulti mai in un errore a causa del denominatore nullo (denom==0)
if (p != NULL && *p == 'x') ...;
}
</source>
 
Si consideri il seguente esempio:
In questo caso la dereferenziazione del puntatore <tt>p</tt> (<tt>*p == 'x'</tt>) viene effettuata solo se esso non è NULL (<tt>p != NULL</tt>) per via della valutazione a corto circuito dell'operatore AND (<tt>&&</tt>). Senza la valutazione a corto circuito esso sarebbe stato dereferenziato anche nel caso in cui <tt>p</tt> valesse NULL, che è un'operazione non ammessa, per cui si sarebbe dovuto ricorrere a
 
<source lang="c">
ifint (pa != NULL) {0;
if (*pa =!= 'x'0 && myfunc(b)) ...;
{
do_something();
}
</source>
 
In questo esempio, la valutazione a cortocircuito garantisce che <code>myfunc(b)</code> non venga mai chiamata. Questo perché l'espressione <code>a != 0</code> risulta in ''false''. Questa caratteristica permette due utili costrutti di programmazione. Come prima cosa, la prima sotto-espressione può essere usata per controllare se è necessario un ulteriore calcolo e se il risultato è ''false'' si possono eliminare i calcoli non necessari del secondo argomento. Secondariamente, permette un costrutto dove la prima espressione garantisce una condizione senza la quale la seconda espressione potrebbe causare un errore di [[Run-time|runtime]]. Essi sono entrambi illustrati nei seguenti codici C dove la valutazione minima evita sia la dereferenziazione con puntatore nullo sia un eccesso di prelievi in memoria:
 
<source lang="cpp">
bool is_first_char_valid_alpha_unsafe(const char *p)
{
return isalpha(p[0]); // SEGFAULT altamente probabile con p == NULL
}
 
bool is_first_char_valid_alpha(const char *p)
{
return p != NULL && isalpha(p[0]); // a) nessuna necessità di eseguire isalpha() con p == NULL, b) nessun rischio di SEGFAULT
}
</source>