Почему мое утверждение «если» не выполняется? - PullRequest
5 голосов
/ 20 декабря 2009

Я перехожу с C # на Delphi 2009, мне это очень нравится.

Я написал процедуру бинарного поиска, которая отлично работает. Я добавил простое выражение if-else в конце моего процесса, и оно просто не сработало! Я не вижу в этом ничего плохого, и мне стыдно сказать, что я застрял. Пожалуйста, помогите!

procedure BinSearch;
var
  min,max,mid, x: integer;
  A : array[0..4] of integer;
  rslt : integer;

begin

  writeln('binary search');
  A[0] := 34; A[1] := 65; A[2] := 98; A[3] := 123; A[4] := 176;
  listarray(a);
  x := 62;
  min := 0;
  max := 4;

  repeat
    begin
    mid := (min + max) div 2;
    if x > A[mid] then
      min := mid + 1
    else
      max := mid - 1;
    end;
  until (A[mid] = x) or (min > max);

  writeln(mid);
  writeln(a[mid]);

  if A[mid] = x then
    rslt := mid
  else
    rslt := not mid;

  if 54 = 65 then
    rslt := mid
  else
    rslt := not mid;

end;

Это if A[mid] = x then тот, который не будет стрелять. при отладке не запускаются ни истинные, ни ложные ветви, отладчик просто пропускает их. Также if 54 = 65 then, который является просто тестом, делает то же самое.

Если внутри моего цикла повторения работает нормально, хотя.

Если я копирую задачу if в мини-тестовый процесс, а затем вызываю этот процесс, он работает, поэтому мне кажется, что в процессе есть что-то еще, например пропущенный ;, вызывающий нечто странное, но я не вижу Это. Пожалуйста, помогите!

Ответы [ 4 ]

14 голосов
/ 20 декабря 2009

Компилятор Delphi довольно умен и удачно удалит неиспользуемый код. Когда я компилирую ваш код, я получаю подсказки компилятора, говорящие: «Значение, присвоенное rslt, никогда не использовалось». Поскольку значение никогда не используется, компилятор просто пропускает эти операторы.

Если вы добавите Writeln(rslt); в конец вашей процедуры, вы обнаружите, что отладчик теперь будет отслеживать вашу инструкцию if.

4 голосов
/ 20 декабря 2009

Может случиться так, что отладчик просто пропускает эти операторы, даже если они на самом деле выполняются. Убедитесь, что все параметры включены в параметрах отладки. В Delphi 7 они находятся в Project \ Options на вкладке Compiler.

0 голосов
/ 22 декабря 2009

«rslt» не используется. Поэтому Delphi оптимизирует его.

Очевидно, вы хотите вернуть свой результат. Поэтому измените вашу декларацию на:

procedure BinSearch(var rslt: integer); 

или лучше, сделайте это функцией:

function BinSearch: integer;

и в конце введите:

Result := rslt;

Выполните любое из вышеперечисленных действий, и вы обнаружите, что эти операторы больше не пропускаются, поскольку сейчас используется rslt.

Но вы обнаружите, что у вас возникнут проблемы с вашим утверждением:

rslt := not mid;

потому что середина - это целое число. Я не уверен, что вы хотите вернуть сюда, но я знаю, что вы не хотите, чтобы оператор «not» применялся к «mid».


Посмотрите на этот код, который я получил из викибуков . Это может помочь вам разобраться.

(* Returns index of requested value in an integer array that has been sorted
in ascending order -- otherwise returns -1 if requested value does not exist. *)

function BinarySearch(const DataSortedAscending: array of Integer;
 const ElementValueWanted: Integer): Integer;
var
    MinIndex, MaxIndex: Integer;
    { When optimizing remove these variables: }
    MedianIndex, MedianValue: Integer;
begin
    MinIndex := Low(DataSortedAscending);
    MaxIndex := High(DataSortedAscending);
    while MinIndex <= MaxIndex do begin
        MedianIndex := (MinIndex + MaxIndex) div 2; (* If you're going to change
         the data type here e.g. Integer to SmallInt consider the possibility of
         an overflow. All it needs to go bad is MinIndex=(High(MinIndex) div 2),
         MaxIndex = Succ(MinIndex). *)
        MedianValue := DataSortedAscending[MedianIndex];
        if ElementValueWanted < MedianValue then
            MaxIndex := Pred(MedianIndex)
        else if ElementValueWanted = MedianValue then begin
            Result := MedianIndex;
            Exit; (* Successful exit. *)
        end else
            MinIndex := Succ(MedianIndex);
    end;
    Result := -1; (* We couldn't find it. *)
end;
0 голосов
/ 22 декабря 2009

Оператор "Begin" сразу после оператора "Repeat" не должен быть там. «Повтор» не использует начало. Я бы удалил его, чтобы быть уверенным, что это не вызовет никаких проблем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...