【问题标题】:Why does my "if" statement appear not to run?为什么我的“if”语句似乎没有运行?
【发布时间】:2009-12-20 00:47:25
【问题描述】:

我正在从 C# 跳槽到 Delphi 2009,到目前为止我非常喜欢它。

我写了一个二分查找程序,效果很好。我在 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 不会触发。当调试 true 或 false 分支都不会触发时,调试器会直接跳过它们。 if 54 = 65 then 也只是一个测试。

我的重复循环中的 if 工作正常。

如果我将问题 if 语句复制到一个迷你测试过程中,然后调用它工作的过程,所以它让我认为它是过程中的其他东西,比如缺少 ; 导致一些奇怪的事情发生但我看不到它。请帮忙!

【问题讨论】:

  • 由于 rslt 除了赋值语句之外从未在任何地方使用过,Delphi 编译器将删除该代码块作为优化的一部分。它不会影响源代码,只是不会将该代码写入目标文件。你可能会收到一个编译器警告说 rslt 变量永远不会被使用...
  • 欢迎来到 StackOverflow 和 Delphi。
  • 只是提示,您不需要在重复循环中使用开始-结束对。

标签: delphi debugging


【解决方案1】:

Delphi 编译器非常聪明,它会愉快地删除未使用的代码。当我编译你的代码时,我得到编译器提示说“分配给'rslt'的值从未使用过”。由于从未使用过该值,因此编译器只会跳过这些语句。

如果您在过程末尾添加Writeln(rslt);,您会发现调试器现在将跟踪您的if 语句。

【讨论】:

  • 我以前见过这种行为,我敢打赌这正是正在发生的事情!+1
【解决方案2】:

可能是调试器只是跳过了这些语句,即使它们实际上正在运行。确保在调试选项中打开所有选项。在 Delphi 7 中,它们位于 Compiler 选项卡下的 Project\Options 下。

【讨论】:

  • 感谢您的快速回复。一切都很好 - 它一直在工作!我在调试器选项中看不到任何要更改的内容,但它确实在触发并且只是在调试器中跳过。我猜是因为 if ... else ... ;是一个声明与它有关,但是它非常奇怪调试器将如何在其他地方而不是在其他地方进入相同的代码。主要的是它正在工作。我不再被难住了,这才是最重要的,感谢您的帮助,并为我的驴子问题感到抱歉。
  • 是的,调试版本中的 Delphi 优化器有时对我来说似乎有点过于激进。
【解决方案3】:

“重复”语句之后的“开始”语句不应该在那里。 “重复”不使用开始。我会删除它以确保它不会引起任何问题。

【讨论】:

    【解决方案4】:

    “rslt”未使用。因此 Delphi 对其进行了优化。

    显然,您希望返回结果。因此,将您的声明更改为:

    procedure BinSearch(var rslt: integer); 
    

    或者更好,让它成为一个函数:

    function BinSearch: integer;
    

    最后输入:

    Result := rslt;
    

    执行上述任一操作,您会发现这些语句不再被跳过,因为现在正在使用 rslt。

    但是,你会发现你的陈述有问题:

    rslt := not mid;
    

    因为 mid 是一个整数。我不确定你想在这里返回什么,但我知道你不希望将“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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多