Interpretacja warunków przy operatorach AND i OR

0

Mam pytanie odnośnie interpretacji warunków przez kompilator (dziwnie to napisałem :) ). Czy jeżeli mamy warunek taki:

if (i=2) or (i=3) then ...

albo

if (i=2) and (i=3) then

to, gdy i jest równe 2 (w 1. przypadku) lub i=3 (w drugim), czy jest analizowany następny/e warunek/ki?

0

Nie jest analizowany. Wystarczy sobie napisać taki kod:

procedure TForm1.Button1Click(Sender: TObject);
function test: integer;
begin
  ShowMessage('test');
  result := 2;
end;
var
  X : integer;
begin
  x := 2;
  if (x = 2) or (test = 3) then ShowMessage('ok');
end;

...jeżeli ustawisz x na 2 to nie pokaże sie "test". Możesz też podejrzeć sobie okienko CPU, i jeżeli wiesz coś nt. asseblera to zobaczysz jak ten kod został przetłumaczony.

0

wszystkie warunki są analizowane... i dopiero później stosuej się na nich operacje algebry Boole'a i wychodzi ostateczny wynik - True albo False.

Znaczy jak masz: if (i=2) or (i=3) then to najpierw jest sprawdzany warnukek i=2, potem i=3 i potem jest sprawdzana suma logiczna tych wyników (znaczy ich OR).

Dominik: To w twoim przykładzie rzeczywiście nie będzie analizowane. Ale to wynika już z procesu optymalizacji kodu wynikwoego przez kompilator. Ogólnie jest zawsze analizowany każdy warunek.

0

A jak to sprawdzić? -> stworzyć sobie funkcje, która zwraca wartość Boolean - a w niej ShowMessage() i mamy pewność.

if (Funkcja1()) or (Funkcja2()) then ...
0

Nie jestem w 100% przekonany o swojej racji :0 , ale przerobiłem troche kod:

procedure TForm1.Button1Click(Sender: TObject);
var
  X : integer;
begin
  Randomize;
  x := Random(100); //tego raczej nie zoptymalizuje bo nie wie co zostanie przypisane
  if (x = 2) or (x = 3) then ShowMessage('ok');
end;

i Delphi wygenerowało taki kod asm:

<b>if (x = 2) or (x = 3) then ShowMessage('ok');</b>

cmp eax,$02
jz +$05
cmp eax,$03
jnz +$0a
mov eax,$004515c
call ShowMessage

Nie jestem specjalistą od assemblera, ale wydaje mi się że jeżeli porównanie cmp eax,$02 wypadnie pozytywnie to wykonany zostanie skok o 5 do przodu, co wypada własnie na mov eax,$004515c (trzeba zobaczyć adresy). Czy gdzies sie mylę ?

0

Wszystko zależy od ustawienia przełącznika kompilatora {$BOOLEVAL} (lub {$B}). Jeśli {$BOOLEVAL On}, to wyrażenia są skracane (tzn. jeśli wartość lewego operandu wystarczy do ustalenia wartości wyrażenia, to prawy operand nie jest obliczany). Z tego co podaje Delphi. Almanach, to domyślnym ustawieniem jest {$BOOLEVAL Off}, ale mogło się to oczywiście zmienić.

0

Hmm... Jak dla mnie, to nie jest sprawdzany. Weźcie sobie coś takiego:
var
x: array of integer;
i: integer;
begin
SetLength(x, 5);
i:=8;
If ((i<5) and (i>=0)) or (x[i]=3) then cośtam;
No i teraz, jakby sprawdzał, to by wywalił wam AccesViolation...

0
Adam.Pilorz napisał(a)

No i teraz, jakby sprawdzał, to by wywalił wam AccesViolation...

Włączone skracanie warunków. Pierwszy człon (lewy operand operatora or) jest prawdziwy i to wystarczy - cały warunek jest prawdą. Ale wpisz {$BOOLEVAL Off} i powinno się wykrzaczyć.

1 użytkowników online, w tym zalogowanych: 0, gości: 1