2009-12-20 5 views
5

Я схожу с C# до Delphi 2009, мне это очень нравится.Почему мой оператор «if» не запускается?

Я написал двоичную процедуру поиска, которая отлично работает. Я добавил простую инструкцию 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, который является просто тестом, делает то же самое.

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

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

+6

Поскольку rslt никогда не используется нигде, кроме оператора присваивания, компилятор Delphi удаляет этот фрагмент кода как часть оптимизации. Это не влияет на исходный код, просто не записывает этот код в объектный файл. Вероятно, вы получили предупреждение компилятора о том, что переменная rslt никогда не используется ... – Sparky

+5

Добро пожаловать в StackOverflow и в Delphi. –

+1

Просто подсказка, вам не нужна пара начального конца в цикле повторения. – Todd

ответ

4

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

+0

Спасибо за быстрый ответ. Все в порядке - все работало! Я не мог ничего изменить для параметров отладчика, но он действительно стрелял и просто пропускал в отладчике. Думаю, потому что если ... еще ...; это одно утверждение, что-то с этим связано, однако очень странно, как отладчик будет входить в идентичный код в других местах, а не на других. Главное, это работает. Я больше не тупик, и это главное, спасибо за вашу помощь и прошу прощения за мой вопрос осле. – user235325

+0

Да, оптимизатор Delphi в сборке отладки иногда кажется немного чрезмерно агрессивным для меня. –

14

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

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

+0

Я видел это поведение раньше, и я уверен, что это именно то, что происходит! +1 –

0

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

0

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

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

procedure BinSearch(var rslt: integer); 

или лучше, сделать его функцию:

function BinSearch: integer; 

и в конце положить в:

Result := rslt; 

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

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

rslt := not mid; 

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


Посмотрите на этот код I got from wikibooks. Это может помочь вам понять это.

(* 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; 
Смежные вопросы