Evaluarea scurtcircuitului
Acest articol sau secțiune despre subiectul programării nu menționează sursele necesare sau sunt insuficiente. |
Evaluarea scurtcircuitului , evaluarea minimă sau evaluarea McCarthy este un mecanism legat de operatorii booleni binari prin care al doilea operand este evaluat numai dacă valoarea primului operand nu este suficientă de la sine pentru a determina rezultatul expresiei: atunci când primul argument al operatorul AND
logic este falso
, valoarea întregii expresii trebuie să fie neapărat falso
; și când primul argument al operatorului OR
logic este vero
, valoarea întregii expresii trebuie să fie în mod necesar vero
. În unele limbaje de programare ( Lisp ), operatorii booleni normali sunt scurtcircuitați. În altele ( Ada , Java ), sunt disponibili atât operatori scurtcircuitați, cât și operatori fără scurtcircuit. Pentru unii operatori booleni, cum ar fi Exclusive Disjunction (XOR), nu este posibil să se scurtcircuiteze, deoarece ambii operanzi sunt întotdeauna necesari pentru a determina rezultatul.
Evaluarea scurtcircuitului, furnizată în multe limbaje de programare , este utilizată atât pentru a accelera calculul rezultatului expresiilor , cât și ca formă compactă a unei instrucțiuni condiționate dacă evaluarea celui de-al doilea operand produce efecte secundare .
Suport în limbaje de programare comune
Limba | Operatori dornici | Operatori de scurtcircuit | Tipul rezultatului |
---|---|---|---|
Programare avansată pentru aplicații de afaceri ( ABAP ) | nimeni | and , or | Boolean 1 |
Ada | and , or | and then , or else | Boolean |
ALGOL 68 | și, &, ∧; sau, ∨ | andf , orf (ambele definite de utilizator) | Boolean |
C , Obiectiv-C | nimeni | && , || , ? [1] | int ( && , || ), opnd-dependent ( ? ) |
C ++ 2 | & , | | && , || , ? [2] | Boolean ( && , || ), dependent de opnd ( ? ) |
C # | & , | | && , || , ? , ?? | Boolean ( && , || ), dependent de opnd ( ? , ?? ) |
Limbaj de marcare ColdFusion (CFML) | nimeni | AND , OR , && , || | Boolean |
D 3 | & , | | && , || , ? | Boolean ( && , || ), dependent de opnd ( ? ) |
Eiffel | and , or | and then , or else | Boolean |
Erlang | and , or | andalso , orelse | Boolean |
Fortran 4 | .and. , .or. | .and. , .or. | Boolean |
Du-te , Haskell , OCaml | nimeni | && , || | Boolean |
Java , MATLAB , R , Swift | & , | | && , || | Boolean |
JavaScript , Julia | & , | | && , || | Ultima valoare |
Perioadă | nimeni | and , or , && , || | Ultima valoare |
Lisp , Lua , Scheme | nimeni | and , or | Ultima valoare |
MUMPS (M) | & ! | nimeni | Numeric |
Modula-2 | nimeni | AND , OR | Boolean |
Oberon | nimeni | & , OR | Boolean |
OCaml | nimeni | && , || | Boolean |
Pascal | and , or 5 | and_then , or_else 6 | Boolean |
Perl , Ruby | & , | | && , and , || , or | Ultima valoare |
PHP | & , | | && , and , || , or | Boolean |
Piton | & , | | and , or | Ultima valoare |
Convorbire scurtă | & , | | and: or: 7 | Boolean |
ML standard | Străin | andalso , orelse | Boolean |
Visual Basic .NET | And , Or | AndAlso , de OrElse , OrElse | Boolean |
VBScript , Visual Basic , Visual Basic pentru aplicații (VBA) | And , Or | Case di selezione 8 | Numeric |
Limbajul Wolfram | And @@ {...} , Or @@ {...} | And , Or , && , || | Boolean |
1 ABAP nu are tipuri booleene diferite.
2 În caz de suprasarcină, operatorii &&
și ||
sunt dornici și pot întoarce orice tip.
3 Acest lucru se aplică numai expresiilor evaluate în runtime, static if
și static assert
. Expresiile în inițializatoare statice sau constante de manifest utilizează o evaluare dornică.
4 Operatorii Fortran nu sunt nici scurtați, nici dornici: specificația limbajului permite compilatorului să selecteze metoda de optimizare.
5 Extended Pascal (ISO / IEC 10206: 1990) permite, dar nu necesită, scurtcircuitarea.
6 Extended Pascal (ISO / IEC 10206: 1990 acceptă and_then
și or_else
. [3]
7 Smalltalk folosește semantica de scurtcircuit numai dacă argumentul and:
este un bloc (de exemplu: false and: [Transcript show: 'Non apparirò!']
).
8 limbaje de bază care susțineau instrucțiunile CASE au făcut acest lucru folosind un sistem de evaluare condițională, mai degrabă decât sări de tabele limitate la etichete fixe.
Utilizări comune
Formă compactă de if / else
Într-un script shell :
test -d / tmp / foo || mkdir / tmp / foo
În acest caz, comanda mkdir / tmp / foo este executată numai dacă rezultatul primei comenzi (care verifică existența directorului / tmp / foo) este fals, din cauza evaluării scurtcircuitului SAU operator (denumit | | în scenariu). Reprezintă o formă compactă de
dacă! test -d / tmp / foo; apoi mkdir / tmp / foo; fi
Evitați efectele nedorite ale celui de-al doilea argument
În limbajul C :
if ( denom ! = 0 && num / denom )
{
... // asigură că expresia num / denom nu duce niciodată la o eroare din cauza numitorului nul (denom == 0)
}
Luați în considerare următorul exemplu:
int a = 0 ;
if ( a ! = 0 && myfunc ( b ))
{
face_ceva ();
}
În acest exemplu, evaluarea scurtcircuitului asigură că myfunc(b)
nu este apelat niciodată. Acest lucru se datorează faptului că expresia a != 0
are ca rezultat fals . Această caracteristică permite două construcții utile de programare. În primul rând, prima sub-expresie poate fi utilizată pentru a verifica dacă este nevoie de calcule suplimentare și dacă rezultatul este fals , calculele inutile ale celui de-al doilea argument pot fi eliminate. În al doilea rând, permite o construcție în care prima expresie garantează o condiție fără de care a doua expresie ar putea provoca o eroare de execuție . Ambele sunt ilustrate în următoarele coduri C în care evaluarea minimă evită atât dereferențierea indicatorului nul, cât și un exces de opțiuni de memorie:
bool is_first_char_valid_alpha_unsafe ( const char * p )
{
returnează isalfa ( p [ 0 ]); // foarte probabil SEGFAULT cu p == NULL
}
bool is_first_char_valid_alpha ( const char * p )
{
returnează p ! = NULL && isalpha ( p [ 0 ]); // a) nu este nevoie să executați isalpha () cu p == NULL, b) fără risc de SEGFAULT
}
Notă
- ^ Standardul ISO / IEC 9899, secțiunea 6.5.13
- ^ Proiect ISO / IEC IS 14882.
- ^ and_then - Manualul GNU Pascal , la gnu-pascal.de . Adus la 24 august 2013 .