if(a && b)
{
do something;
}
c'è la possibilità di valutare gli argomenti da destra a sinistra (b -> a)?Ordine di valutazione argomento "IF"?
se "sì", cosa influenza l'ordine di valutazione?
(sto usando VS2008)
if(a && b)
{
do something;
}
c'è la possibilità di valutare gli argomenti da destra a sinistra (b -> a)?Ordine di valutazione argomento "IF"?
se "sì", cosa influenza l'ordine di valutazione?
(sto usando VS2008)
L'ordine di valutazione è specificato dallo standard ed è left-to-right
. L'espressione più a sinistra verrà sempre valutata per prima con la clausola &&
.
Se vuoi b
da valutare prima:
if(b && a)
{
//do something
}
Se entrambi gli argomenti sono i metodi e si desidera entrambi da valutare indipendentemente dal loro risultato:
bool rb = b();
bool ra = a();
if (ra && rb)
{
//do something
}
questo è un sollievo ... per una volta C++ ha il comportamento predefinito corretto invece di uno sorprendentemente chiaro –
@AviadRozenhek: hai ragione di essere spaventato perché in effetti è possibile che l'espressione 'b' sia valutata prima dell'espressione' a'. Perché ciò avvenga, tuttavia, l'operatore non deve essere l'operatore '&&' logico-e, ma un sovraccarico per i tipi definiti dall'utente.In questo caso l'ordine di valutazione degli argomenti non è specificato (e peggio di quello che non si può nemmeno aspettare un ordinamento reale perché la valutazione può anche essere "mescolata": un po 'di a, quindi alcuni di 'b', quindi più di 'a', poi ancora alcuni bit rimanenti di' b' e infine viene chiamato l'operatore personalizzato). – 6502
Che succede se invece si utilizza '||'? _should_ rimane lo stesso a meno che alcune ottimizzazioni del compilatore non lo facciano, correggere @ 6502? – mdw7326
In questo caso, dal momento che si sta utilizzando &&
, a
sarà sempre essere valutati in primo luogo perché il risultato viene utilizzato per determinare se o non cortocircuitare l'espressione.
Se a
restituisce false, quindi b
non è autorizzato a valutare affatto.
... a meno che l'operatore && non sia sovraccarico. Che è possibile, ma considerato come un cattivo design. – dalle
Non ci ho pensato. Buon punto :) – Mysticial
Sono certo che quanto segue è il caso, ma è sicuro fare qualcosa del genere: 'Obj * obj; if (obj && obj-> foo()) {...} ' Suppongo che controlli che wheter obj non sia NULL e solo se non è NULL, controllerà il risultato di' obj-> foo() ', destra? –
Valuterà da sinistra a destra e cortocircuiterà la valutazione se possibile (ad esempio, se una valutazione è falsa, non valuterà b).
Se si preoccupa dell'ordine in cui vengono valutati, è sufficiente specificarli nell'ordine di valutazione desiderato nella dichiarazione if.
La domanda riguarda C++, non C# (anche se probabilmente hai ragione che entrambi fanno la stessa cosa, ispirati a ciò che fa C). –
oops! Presumo che siano entrambi gli stessi come dici tu. –
Con C++ ci sono solo alcuni operatori che garantiscono l'ordine di valutazione
operator &&
valuta prima l'operando sinistro e se il valore è logicamente false
, allora evita di valutare l'operando corretto. L'uso tipico è ad esempio if (x > 0 && k/x < limit) ...
che evita problemi di divisione per zero.
operator ||
valuta prima l'operando sinistro e se il valore è logicamente true
, quindi evita di valutare l'operando corretto. Ad esempio if (overwrite_files || confirm("File existing, overwrite?")) ...
non chiederà conferma quando è impostato il flag overwrite_files
.
operator ,
valuta prima l'operando sinistro e poi l'operando destro, restituendo il valore dell'operando destro. Questo operatore non viene usato molto spesso. Si noti che le virgole tra i parametri di una chiamata di funzione sono non gli operatori virgola e l'ordine di valutazione non è garantito.
ternario operatore x?y:z
Esamina x
prima, e poi a seconda del valore logico del risultato valuta o unicamente y
o solo z
.
Per tutti gli altri operatori l'ordine di valutazione non è specificato.
la situazione è in realtà peggiore, perché non è che l'ordine non è specificato, ma che non c'è nemmeno un "ordine" per l'espressione a tutti, e per esempio in
std::cout << f() << g() << x(k(), h());
è possibile che funzioni sarà chiamato nell'ordine h-g-k-x-f
(questo è un po 'inquietante perché il modello mentale dell'operatore <<
trasmette in qualche modo l'idea di sequenzialità ma in realtà rispetta la sequenza solo nell'ordine i risultati sono messi nello stream e non nell'ordine i risultati sono calcolata).
Ovviamente le dipendenze del valore nell'espressione possono introdurre qualche garanzia di ordine; ad esempio nell'espressione precedente è garantito che sia k()
sia h()
verranno chiamati prima dello x(...)
poiché i valori di ritorno di entrambi sono necessari per chiamare x
.
Si noti inoltre che le garanzie per &&
, ||
e ,
sono valide solo per operatori predefiniti. Se sovraccarichi questi operatori per i tuoi tipi, saranno in quel caso come normali chiamate di funzione e l'ordine di valutazione degli operandi non sarà specificato.
Solo un pizzico, ma le dipendenze di valore impongono anche un ordine. In un'espressione come '(a + b) * c',' a' e 'b' devono essere valutati prima dell'aggiunta e l'aggiunta deve avvenire prima della moltiplicazione. Generalmente, questo effetto non è osservabile, ma se gli operatori sono sovraccarichi, potrebbe essere visibile. –
@JamesKanze: Ok. Penso che sia ovvio per un linguaggio come il C++, ma ha aggiunto comunque una nota per quello. – 6502
Ogni valore di calcolo e lato effetto della prima (sinistra) argomentazione incorporato operatore logico AND & & e il built-in OR logico operatore || viene sequenziato prima di ogni calcolo del valore e dell'effetto collaterale del secondo argomento (a destra).
Leggi qui per una spiegazione più esaustiva delle regole stabilite: order evaluation
L'operatore &&
valuta sempre il suo operando a sinistra prima. Per esempio:
if (a && b)
{
//block of code
}
Se a
è falso, allora b
valutazione non sarà garantito.
Se si desidera b
da valutare prima, e a
solo se b
è vero, è sufficiente scrivere l'espressione viceversa:
if (b && a)
{
//block of code
}
'if (b && a)' lo farà per voi. –
Cosa sono 'a' e' b'? –
prova se (b && a). prova questo link: http://msdn.microsoft.com/en-us/library/2bxt6kc4.aspx – CloudyMarble