2009-12-20 50 views
5

我從C#跳到Delphi 2009,我非常喜歡它。爲什麼我的「if」陳述似乎不運行?

我寫了一個二進制搜索過程,它工作正常。我在我的proc結尾添加了一個簡單的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,所以這讓我覺得這是別人像一個丟失;的進程內的東西造成一些奇怪的情況發生,但我無法看到它。請幫忙!

+6

由於rslt從來沒有用在除賦值語句之外的任何地方,Delphi編譯器在優化過程中刪除了該塊代碼。它不會影響源代碼,只是不會將該代碼寫入目標文件。您可能得到了一個編譯器警告,rslt變量從未使用過...... – Sparky 2009-12-20 01:33:59

+5

歡迎使用StackOverflow和Delphi。 – 2009-12-20 02:29:04

+1

只是一個提示,你不需要在repeat-until循環中使用起始端對。 – Todd 2009-12-20 19:25:37

回答

4

這可能是調試器只是跳過這些語句,即使它們實際上在運行。確保在調試選項中打開了所有選項。在Delphi 7中,它們位於Compiler選項卡下的Project \ Options下。

+0

感謝您的快速響應。一切都很好 - 它一直在工作! 我在調試器選項中看不到任何要更改的內容,但它確實正在觸發並在調試器中跳過。我猜是因爲如果...其他......;是一個聲明與它有關,但它很奇怪調試器將如何在其他地方進入相同的代碼,而不是在其他地方。主要的是它是工作壽。 我不再難倒了,這是主要的,謝謝你的幫助和我的驢子問題。 – user235325 2009-12-20 01:17:25

+0

是的,調試版本中的Delphi優化器有時對我來說看起來有些過於激進。 – 2009-12-20 01:39:40

14

Delphi編譯器非常聰明,它會愉快地移除未使用的代碼。當我編譯你的代碼時,我得到編譯器提示「賦值給'rslt'從未使用過」。由於該值從不使用,因此編譯器會跳過這些語句。

如果您在程序結束時添加Writeln(rslt);,您會發現調試程序現在會跟蹤您的if語句。

+0

我以前見過這種行爲,我敢打賭發生了什麼事情!+1 – 2009-12-21 15:37:18

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;