2012-05-23 39 views
7

tôi có các thủ tục sau:Tại sao biên dịch bỏ qua gán biến

procedure GetDegree(const num : DWORD ; var degree : DWORD ; min ,sec : Extended); 
begin 
    degree := num div (500*60*60); 
    min := num div (500*60) - degree *60; 
    sec := num/500 - min *60 - degree *60*60; 
end; 

Sau biến mức độ được gán bỏ qua debugger đến hết thủ tục. Tại sao vậy?

Trả lời

17

Đó là một tối ưu hóa. Các biến số minsec được truyền theo giá trị. Điều đó có nghĩa là các thay đổi đối với chúng không được người gọi nhìn thấy và được đặt riêng cho quy trình này. Do đó trình biên dịch có thể làm việc ra rằng gán cho họ là vô nghĩa. Các giá trị được gán cho các biến không bao giờ được đọc. Vì vậy, trình biên dịch chọn để tiết kiệm thời gian và bỏ qua các bài tập. Tôi hy vọng rằng bạn có nghĩa là để khai báo các thủ tục như thế này:

procedure GetDegree(const num: DWORD; var degree: DWORD; var min, sec: Extended); 

Như tôi đã nói trong câu hỏi trước đó của bạn, có không thực sự nhiều điểm trong việc sử dụng Extended. Bạn sẽ tốt hơn với một trong các loại điểm nổi tiêu chuẩn, Single hoặc Double. Hoặc thậm chí sử dụng số chung Real để ánh xạ tới Double.

Ngoài ra, bạn đã khai báo min là loại dấu phẩy động, nhưng phép tính tính một số nguyên. Câu trả lời của tôi cho câu hỏi trước của bạn là khá chính xác trong lĩnh vực này.


Tôi khuyên bạn nên tạo bản ghi để giữ các giá trị này. Thông qua ba biến riêng biệt xung quanh làm cho giao diện chức năng của bạn rất lộn xộn và phá vỡ đóng gói. Ba giá trị này chỉ có ý nghĩa khi xem xét tổng thể.

type 
    TGlobalCoordinate = record 
    Degrees: Integer; 
    Minutes: Integer; 
    Seconds: Real; 
    end; 

function LongLatToGlobalCoordinate(const LongLat: DWORD): TGlobalCoordinate; 
begin 
    Result.Degrees := LongLat div (500*60*60); 
    Result.Minutes := LongLat div (500*60) - Result.Degrees*60; 
    Result.Seconds := LongLat/500 - Result.Minutes*60 - Result.Degrees*60*60; 
end; 

function GlobalCoordinateToLongLat(const Coord: TGlobalCoordinate): DWORD; 
begin 
    Result := Round(500*(Coord.Seconds + Coord.Minutes*60 + Coord.Degrees*60*60)); 
end; 
+0

Cảm ơn một lần nữa David bạn đã là một trợ giúp to lớn hôm nay.Không biết về những sự tối ưu chết tiệt này tôi có thể loại bỏ chúng khỏi đoạn mã này không? – opc0de

+6

@ opc0de Bạn không muốn xóa các tối ưu. Bạn muốn sửa mã của bạn để nó trả về giá trị 'min' và' sec' cho người gọi. Nếu không, tại sao bạn phải tính toán chúng ngay từ đầu? –

+0

Ok đã nhận ngay bây giờ. Cảm ơn một lần nữa sai lầm ngu ngốc :)! – opc0de

Các vấn đề liên quan