2011-07-23 29 views
6

Hôm nay một trong những người bạn của tôi hỏi tôi về dưới mã:kết quả trong mã đơn giản khi biến được uninitialized

var 
    a: Integer; 
begin 
    ShowMessage(IntToStr(a)); 
end; 

này được biến cục bộ và không được khởi tạo, ok?

đang Đặt trong OnClick sự kiện của một thành phần nút và sau đó chạy mã trong ba cách khác nhau dưới đây:

  1. Bấm vào nút và xem kết quả, kết quả = 1635841
  2. Nhấn phím Enter và xem kết quả, kết quả = 1
  3. Nhấn phím Space và xem kết quả, reuslt = 1636097

tôi thử nghiệm mã trong hai máy tính khác nhau & thấy kết quả tương tự, bất kỳ ý tưởng về t của anh ấy ?

+0

Trên máy của tôi, tôi nhận được các kết quả khác nhau. Tôi cũng nhận được kết quả khác nhau mỗi khi tôi chạy chương trình. (Tuy nhiên, tôi thấy không có sự khác biệt tùy thuộc vào cách nút được nhấp.) –

+0

Những gì tôi nhận được trên máy tính là 5734816 là giá trị được lưu trữ trong đăng ký EBX)) –

+8

Được thăng hạng vì rõ ràng đây là một người mới chỉ học Delphi. Bạn không chắc chắn tại sao các downvotes? Chào mừng bạn đến với SO, Geek. –

Trả lời

10

Vì biến không được khởi tạo, giá trị của nó có thể là bất kỳ thứ gì. Vì kết quả của bạn là 'một cái gì đó', không có gì bất thường ở tất cả diễn ra ở đây.

+1

+1 Một điều thú vị là nó đôi khi thậm chí còn đi đến chuỗi http://stackoverflow.com/questions/3250827/initialise-string-function-result –

+0

Không có @Boris, vấn đề kết quả chuỗi là một vấn đề khác. Kết quả chuỗi được thực sự khởi tạo bởi các hàm gọi, không phải là hàm được gọi, đó là lý do tại sao chúng xuất hiện để giữ lại giá trị đó. –

+1

@Cosmin Kết quả chuỗi được instancied, không được khởi tạo bởi chức năng gọi.Nếu bạn gọi vài lần một hàm với chuỗi kết quả không được gán bên trong hàm, nếu bạn thay đổi nội dung giữa hai cuộc gọi, nội dung sẽ vẫn bị ảnh hưởng: thể hiện chuỗi được khởi tạo, trước hết được '', nhưng sẽ không đặt lại thành '' cho mỗi cuộc gọi hàm. Chỉ tham số 'out aText: string;' sẽ xóa chuỗi trước mỗi cuộc gọi. –

1

Xem điều này tương tự Stackoverflow question.

Trong biến cục bộ Delphi không được khởi tạo theo mặc định. Lập trình viên chịu trách nhiệm về điều đó và phải luôn đặt giá trị trước khi đọc nó. Giá trị của một biến đơn vị phụ thuộc vào nội dung của các tế bào bộ nhớ được phân bổ thực tế được sử dụng cho biến đó. Vì vậy, bất kỳ giá trị có thể ở đây.

+0

tôi biết điều này! và tôi nói trong bài đăng đầu tiên của tôi rằng @ "Đây là biến địa phương và chưa được khởi tạo"! –

+1

Vậy câu hỏi ở đây là gì? Ở cấp độ ngôn ngữ Delphi, tất cả những gì bạn cần biết là giá trị của một biến chưa được khởi tạo là không xác định. Nếu bạn thực sự muốn biết chính xác những gì đang xảy ra, bạn phải nhìn vào mức mã máy. Nhưng mã được tạo ra phụ thuộc rất nhiều vào phiên bản trình biên dịch và cờ trình biên dịch (chế độ gỡ lỗi, mức tối ưu hóa, v.v.). Thông thường bộ nhớ cho các biến cục bộ được cấp phát từ ngăn xếp. Và ngăn xếp tăng lên và co lại vĩnh viễn trong quá trình thực thi chương trình do đó các biến cục bộ mới có thể chứa bất kỳ giá trị nào, có thể là địa chỉ trả lại cũ được sử dụng, nhưng ai quan tâm? – vanje

2
procedure TForm1.Button1Click(Sender: TObject); 
var 
    a: Integer; 
begin 
    ShowMessage(IntToStr(Integer(a))); 
end; 

procedure TForm1.Button2Click(Sender: TObject); 
begin 
ShowMessage(IntToStr(Integer(Pointer(TButtonControl(Button1))))); 
end; 

trên máy tính của tôi mã này tạo ra cùng một thông điệp như trình biên dịch sử dụng ebx đăng ký cho một biến, trong khi TButtonControl.WndProc sử dụng ebx để lưu trữ con trỏ đến Tự (như EAX sẽ ghi đè sau khi gọi hàm WinAPI từ TbuttonControl.WndProc) là button1 trước khi gọi trình xử lý thực tế Button1Click. Vì vậy, than ôi, trên văn bản thông điệp Delphi 2007 là quá dự đoán được.

[sửa] Bạn có thể xem những gì đang xảy ra bên trong VCL khi gỡ lỗi nếu bạn bật Sử dụng debug DCUs tùy chọn trong tùy chọn biên dịch dự án của bạn Compiler-> Debugging-> Sử dụng debug DCUs.

+2

Không thêm thư mục nguồn Delphi vào đường dẫn tìm kiếm trình biên dịch của bạn. Bạn chạy các nguy cơ của Delphi biên dịch lại những đơn vị. Để gỡ lỗi thông qua các đơn vị VCL, hãy bật tùy chọn "gỡ lỗi DCU", bổ sung thư mục gỡ lỗi-DCU vào đường dẫn tìm kiếm; thư mục đó không chứa mã nguồn. –

+0

@Rob cảm ơn bạn đã sửa lỗi –

+0

đã được khắc phục - có vẻ như tôi cũng đã từng bước vào cùng một rake và sau đó –

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