2009-12-20 31 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;