Scurtcircuitarea în C++: ordinea condițiilor && și ||
Înțelege când C++ nu mai evaluează a doua condiție. Protejează indicii și împărțirea la zero și diferențiază && de operatorul pe biți &.
În acest material
În condiția i<n && a[i]==x, întâi verificăm dacă i este în intervalul permis. Dacă i<n este fals, C++ nu mai evaluează a[i]==x. Acest comportament se numește scurtcircuitare: rezultatul este deja cunoscut și a doua expresie nu mai este necesară.
De ce ordinea protejează accesul
Operatorul logic && înseamnă „și”. Pentru a fi adevărat, ambele condiții trebuie să fie adevărate. După prima condiție falsă, întregul rezultat este fals. În schimb, || înseamnă „sau”; după prima condiție adevărată, rezultatul este deja adevărat.
În exemplul cu vectorul presupunem și i≥0. Dacă i poate fi negativ, verificarea completă trebuie să includă i>=0 înaintea accesului. Numărul n trebuie să reprezinte dimensiunea logică a datelor, nu o limită aleasă la întâmplare.
Inversarea ordinii în a[i]==x && i<n elimină protecția: accesul are loc înainte să afli dacă i este valid. Faptul că o condiție logică de „și” poate fi comutativă în matematică nu înseamnă că evaluarea expresiilor unui program poate fi reordonată fără consecințe.
Împărțirea este un al doilea exemplu
Condiția b!=0 && a%b==0 verifică întâi divizorul. Dacă b este zero, restul nu se calculează. Acest exemplu presupune separat că operația este reprezentabilă pentru celelalte valori acceptate; scurtcircuitarea nu rezolvă toate limitele tipurilor numerice.
Cu ||, un caz de bază poate elimina calculul următor. De exemplu, la o verificare în care zero este acceptat direct, x==0 || ... nu mai execută partea din dreapta pentru x=0. Acea parte trebuie totuși să fie validă pentru toate celelalte intrări.
La expresia i<n && a[i]>0, dacă i=n, prima condiție este falsă și accesul a[i] nu se evaluează. Ordinea inversă ar citi înainte de verificare.Mărește schema ↗
Un singur & nu este o prescurtare
Operatorul & lucrează pe biți pentru operanzi întregi. Nu oferă protecția de scurtcircuitare a lui &&. Chiar dacă uneori produce același rezultat numeric pe valori 0 și 1, nu este un substitut sigur într-o condiție care protejează memoria.
Evită condițiile care modifică multe variabile. Dacă un apel din dreapta are efecte, acestea nu se produc pe toate ramurile. Separarea pașilor poate face programul mai ușor de verificat decât o expresie compactă cu incrementări și apeluri.
Verifică frontiera, nu doar cazul normal
Pentru căutare, testează i=0, i=n-1 și i=n. Pentru împărțire, testează b=0 și un divizor valid. Urmărește ce expresii se execută efectiv, nu doar valoarea finală adevărat sau fals.
Revezi expresiile logice, structura if și indicii vectorilor. Regula pentru && este precizată în specificația C++.
Întrebări frecvente
Ce înseamnă scurtcircuitarea unei condiții în C++?
La operatorii logici obișnuiți, && nu mai evaluează operandul drept dacă cel stâng este fals, iar || nu îl mai evaluează dacă cel stâng este adevărat. Rezultatul logic este deja determinat.
De ce verific indicele înainte de accesul în vector?
O condiție de validitate pusă prima poate opri evaluarea înainte de a[i]. Pentru un indice care poate fi negativ, verifică și limita inferioară, nu doar i < n.
Pot folosi & în loc de && pentru protejarea unui acces?
Nu. Operatorul pe biți & nu oferă scurtcircuitarea lui &&. O expresie din dreapta poate fi evaluată chiar dacă verificarea din stânga ar fi suficientă pentru a respinge accesul.