2010-07-13 17 views
10
Program ConstTest; 
    Const constVar = 1; 
    Begin 
    constVar := 3; 
    WriteLn(constVar); 
    End. 

Rõ ràng là mã trên sẽ không biên dịch, bởi vì nó không đúng để thay đổi giá trị của hằng số. Tuy nhiên, đoạn mã sau sẽ biên dịch, và sẽ trở lại "1; 5; 3;", mặc dù mảng là một const:Tại sao mảng Pascal const không thực sự là hằng số?

Program ConstTest; 
    Const constArr:Array [1..3] Of ShortInt = (1,2,3); 
    Var i:ShortInt; 
    Begin 
    constArr[2] := 5; 
    For i:=1 To 3 Do WriteLn(constArr[i],'; '); 
    End. 

Vì vậy, những gì gây ra hành vi này? Tại sao hằng số không thực sự là hằng số?

Tôi đang sử dụng FreePascal Compiler 2.2.0 cho Win32.

+0

Xem thêm http://stackoverflow.com/questions/48934/in-delphi-7-why-can-i-assign-a-value-to-a-const và http://stackoverflow.com/questions/2714365/delphi-all-hằng số-là-hằng-nhưng-một số-là-nhiều-hằng-hơn-những người khác. –

Trả lời

11

Những gì bạn có ở đây là hằng số được nhập. Các hằng số đã nhập khác với các hằng số thông thường thông thường (a.k.a. hằng số thực sự), đó là số constVar của bạn. Lưu ý cách bạn không cần chỉ định loại trên constVar; nếu bạn đã có, bạn có thể thấy rằng trình biên dịch cho phép bạn gán các giá trị mới cho nó, quá:

const 
    constVar: Integer = 1; 

The Free Pascal manual mô tả hằng gõ:

Trái với hằng số bình thường, một giá trị có thể được gán cho chúng ở thời gian chạy. Đây là một khái niệm cũ từ Turbo Pascal, đã được thay thế bằng sự hỗ trợ cho các biến được khởi tạo: Để biết mô tả chi tiết, xem phần 4.4, trang 183.

Hỗ trợ gán giá trị cho các hằng số đã nhập được điều khiển bởi chỉ thị {$J}: có thể tắt, nhưng được bật theo mặc định (cho khả năng tương thích với Turbo Pascal). Các biến được khởi tạo luôn được cho phép.

Đối với biến được khởi tạo, thay thế const bằng var trong tuyên bố của bạn. Nó sẽ nhận được giá trị của nó khi nhập phạm vi. Hoặc, tắt chỉ thị $J trước tuyên bố đã nhập không đổi:

{$J-} 
const 
    constArr: array [1..3] of ShortInt = (1, 2, 3); 
{$J+} 

Cho dù bạn bật lại sau đó tùy thuộc vào bạn.


Hằng số đã nhập có thể sửa đổi được do cách chúng được lưu trữ trong bộ nhớ. Trên thực tế, nó là chúng được lưu trữ trong bộ nhớ rằng chúng ban đầu có thể sửa đổi được. Hằng số thông thường không được lưu trữ trong bộ nhớ như các đối tượng riêng biệt. Khi trình biên dịch gặp phải một hằng số bình thường được sử dụng trong chương trình của bạn, nó sẽ thay thế nó trong dòng với giá trị của hằng số, giống như bạn đã sử dụng một chữ trong vị trí của nó. Mặt khác, một hằng số được nhập nằm ở vị trí riêng của nó trong bộ nhớ và khi bạn tham chiếu một mã, giá trị của nó được đọc từ bộ nhớ, giống như sử dụng bất kỳ biến nào khác. Bạn sử dụng các hằng số đã nhập khi không có cú pháp nào có sẵn cho chữ - ví dụ: bạn không thể có mảng hoặc bản ghi âm.

0

Vâng, nếu bạn cũng biết C, đây là một vài điểm tương đồng:

Trong [Turbo/miễn phí] Pascal, viết một cái gì đó như thế này:

const 
    MIN = 5; 
    MAX = 10; 

là tương đương với việc này trong C:

#define MIN 5 
#define MAX 10 

Tức là, đó là biểu tượng thời gian biên dịch thay thế như các áp phích khác nói.

Với bản ghi và mảng, (hằng số đã nhập), biểu thức "const" chỉ là cách khởi tạo khối bộ nhớ được liên kết với biểu tượng trình liên kết.

TODO: ví dụ về lượt truy cập.

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