2009-12-20 44 views
5

Tôi đang đào thoát từ C# sang Delphi 2009, tôi rất thích nó cho đến nay.Tại sao câu lệnh "if" của tôi xuất hiện không chạy?

Tôi đã viết một quy trình tìm kiếm nhị phân, hoạt động tốt. Tôi đã thêm một tuyên bố if-else đơn giản vào cuối proc của tôi và nó không cháy! Tôi không thể nhìn thấy bất cứ điều gì sai trái với nó và xấu hổ khi phải nói rằng tôi bị mắc kẹt. Hãy giúp tôi!

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; 

Đó là số if A[mid] = x then sẽ không kích hoạt. khi gỡ lỗi không đúng hoặc nhánh giả cháy, trình gỡ lỗi chỉ bỏ qua ngay trên chúng. Ngoài ra, if 54 = 65 then chỉ là một thử nghiệm cũng vậy.

Nếu bên trong vòng lặp lặp lại của tôi hoạt động tốt.

Nếu tôi sao chép vấn đề nếu tuyên bố vào một proc thử nghiệm nhỏ, và sau đó gọi proc nó hoạt động, do đó, nó làm cho tôi nghĩ rằng nó là cái gì khác trong proc như một thiếu ; gây ra một cái gì đó kỳ lạ xảy ra nhưng tôi không thể nhìn thấy nó . Hãy giúp tôi!

+6

Vì rslt không bao giờ được sử dụng ở bất kỳ đâu ngoài câu lệnh gán, trình biên dịch Delphi loại bỏ đoạn mã đó như một phần của tối ưu hóa. Nó không ảnh hưởng đến mã nguồn, chỉ đơn giản là không viết mã đó vào tệp đối tượng. Bạn có thể có một cảnh báo trình biên dịch rằng biến rslt không bao giờ được sử dụng ... – Sparky

+5

Chào mừng bạn đến với StackOverflow và Delphi. –

+1

Chỉ cần một mẹo, bạn không cần một cặp bắt đầu trong một vòng lặp lặp lại cho đến khi. – Todd

Trả lời

4

Có thể là trình gỡ lỗi chỉ bỏ qua các câu lệnh đó mặc dù chúng thực sự đang chạy. Đảm bảo rằng tất cả các tùy chọn được bật trong các tùy chọn gỡ lỗi. Trong Delphi 7, chúng nằm trong Project \ Options trong tab Compiler.

+0

Cảm ơn bạn đã phản hồi nhanh. Tất cả là tốt - nó đã được làm việc tất cả cùng! Tôi không thể thấy bất kỳ điều gì thay đổi trong các tùy chọn trình gỡ lỗi, nhưng nó thực sự đã kích hoạt và chỉ bỏ qua trong trình gỡ lỗi. Tôi đoán vì nếu ... khác ...; là một tuyên bố là một cái gì đó để làm với nó, tuy nhiên nó rất lạ như thế nào trình gỡ lỗi S step bước vào mã giống hệt nhau ở những nơi khác, và không phải trên những người khác. Điều chính là nó đang làm việc tho. Tôi không còn bối rối và đó là điều chính, nhờ sự giúp đỡ của bạn và sry cho câu hỏi lừa của tôi. – user235325

+0

Vâng, trình tối ưu hóa Delphi trong bản dựng gỡ lỗi đôi khi có vẻ hơi quá hung hăng với tôi. –

14

Trình biên dịch Delphi khá thông minh và nó sẽ xóa mã không sử dụng một cách hạnh phúc. Khi tôi biên dịch mã của bạn, tôi nhận được gợi ý trình biên dịch nói rằng "Giá trị được gán cho 'rslt' không bao giờ được sử dụng". Vì giá trị không bao giờ được sử dụng, trình biên dịch chỉ bỏ qua các câu lệnh đó.

Nếu bạn thêm Writeln(rslt); vào cuối quy trình, bạn sẽ thấy rằng trình gỡ lỗi hiện sẽ theo dõi thông báo if của bạn.

+0

Tôi đã nhìn thấy hành vi này trước đây và tôi đặt cược đó chính xác là những gì đang diễn ra! +1 –

0

Câu lệnh "Bắt đầu" ngay sau câu lệnh "Lặp lại" không nên ở đó. "Lặp lại" không sử dụng bắt đầu. Tôi sẽ loại bỏ nó chỉ để chắc chắn rằng nó không gây ra bất kỳ vấn đề.

0

"rslt" không được sử dụng. Do đó Delphi tối ưu hóa nó ra.

Rõ ràng, bạn muốn trả về kết quả của mình. Vì vậy, thay đổi tuyên bố của bạn để:

procedure BinSearch(var rslt: integer); 

hoặc tốt hơn, làm cho nó một chức năng:

function BinSearch: integer; 

và cuối cùng đưa vào:

Result := rslt; 

Thực hiện một trong những điều trên, và bạn sẽ thấy rằng những câu lệnh đó không còn bị bỏ qua vì rslt hiện đang được sử dụng.

Tuy nhiên, bạn sẽ tìm thấy bạn sẽ có một vấn đề với tuyên bố của bạn:

rslt := not mid; 

vì giữa là một số nguyên. Tôi không chắc chắn những gì bạn muốn quay trở lại đây, nhưng tôi biết bạn không muốn nhà điều hành "không" được áp dụng cho "giữa".


Nhìn mã này I got from wikibooks. Nó có thể giúp bạn tìm ra.

(* 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; 
Các vấn đề liên quan