Hãy thảo luận điều này trong các điều khoản C/C++; có một số công cụ bổ sung để biết về mảng C# nhưng nó không thực sự liên quan đến vấn đề này.
Với một loạt các giá trị số nguyên 16-bit:
short[5] myArray = {1,2,3,4,5};
gì thực sự xảy ra là máy tính đã phân bổ một khối không gian trong bộ nhớ. Khối bộ nhớ này được dành riêng cho mảng đó, chính xác là kích thước cần thiết để giữ mảng đầy đủ (trong trường hợp của chúng tôi 16 * 5 == 80 bit == 10 byte), và tiếp giáp. Những sự kiện này là givens; nếu có hoặc không có điều gì trong số đó là đúng trong môi trường của bạn tại bất kỳ thời điểm nào, bạn thường gặp rủi ro cho chương trình của bạn bị lỗi do truy cập một lần.
Vì vậy, với cấu trúc này, biến số myArray
thực sự là, đằng sau hậu trường, là địa chỉ bộ nhớ của sự bắt đầu của khối bộ nhớ. Điều này cũng thuận tiện, sự khởi đầu của phần tử đầu tiên. Mỗi phần tử bổ sung được xếp hàng trong bộ nhớ ngay sau lần đầu tiên, theo thứ tự. Khối bộ nhớ phân bổ cho myArray
có thể trông như thế này:
00000000000000010000000000000010000000000000001100000000000001000000000000000101
^ ^ ^ ^ ^
myArray([0]) myArray[1] myArray[2] myArray[3] myArray[4]
Nó được coi là một hoạt động liên tục thời gian để truy cập vào một địa chỉ bộ nhớ và đọc một hằng số của byte. Như trong hình trên, bạn có thể lấy địa chỉ bộ nhớ cho mỗi thứ nếu bạn biết ba điều; sự bắt đầu của khối bộ nhớ, kích thước bộ nhớ của mỗi phần tử và chỉ mục của phần tử bạn muốn. Vì vậy, khi bạn yêu cầu myArray[3]
trong mã của bạn, yêu cầu được trở thành một địa chỉ bộ nhớ bằng phương trình sau đây:
myArray[3] == &myArray+sizeof(short)*3;
Như vậy, với một tính liên tục theo thời gian, bạn đã tìm thấy địa chỉ bộ nhớ của phần tử thứ tư (chỉ số 3), và với một hoạt động liên tục khác (hoặc ít nhất được xem như vậy; độ phức tạp truy cập thực tế là chi tiết phần cứng và đủ nhanh mà bạn không nên quan tâm), bạn có thể đọc bộ nhớ đó. Đây là, nếu bạn đã từng tự hỏi, tại sao các chỉ mục của các bộ sưu tập trong hầu hết các ngôn ngữ kiểu C bắt đầu từ số không; phần tử đầu tiên của mảng bắt đầu tại vị trí của mảng, không có offset (sizeof (bất cứ điều gì) * 0 == 0)
Trong C#, có hai sự khác biệt đáng chú ý. C# mảng có một số thông tin tiêu đề được sử dụng cho CLR. Header đến trước trong khối bộ nhớ, và kích thước của tiêu đề này là không đổi và được biết đến, vì vậy phương trình giải quyết chỉ có một sự khác biệt quan trọng:
myArray[3] == &myArray+headerSize+sizeof(short)*3;
C# không cho phép bạn để tham khảo trực tiếp bộ nhớ trong quản lý của nó môi trường, nhưng bản thân thời gian chạy sẽ sử dụng một cái gì đó như thế này để thực hiện truy cập bộ nhớ ngoài heap. Một điều thứ hai, cũng phổ biến đối với hầu hết các hương vị của C/C++, là một số loại nhất định luôn được xử lý bằng "tham chiếu". Bất cứ điều gì bạn phải sử dụng từ khóa new
để tạo là một kiểu tham chiếu (và có một số đối tượng, như chuỗi, cũng là kiểu tham chiếu mặc dù chúng trông giống như kiểu giá trị trong mã). Một kiểu tham chiếu, khi được khởi tạo, được đặt trong bộ nhớ, không di chuyển và thường không được sao chép. Bất kỳ biến đại diện cho đối tượng đó là như vậy, đằng sau hậu trường, chỉ là địa chỉ bộ nhớ của đối tượng trong bộ nhớ. Mảng là kiểu tham chiếu (nhớ myArray chỉ là một địa chỉ bộ nhớ). Mảng của các kiểu tham chiếu là các mảng của các địa chỉ bộ nhớ này, do đó truy cập một đối tượng là một phần tử trong một mảng là một quá trình gồm hai bước; đầu tiên bạn tính toán địa chỉ bộ nhớ của phần tử trong mảng và nhận được điều đó.Đó là một địa chỉ bộ nhớ khác, đó là vị trí của đối tượng thực tế (hoặc ít nhất là dữ liệu có thể thay đổi của nó; cách các kiểu hợp chất được cấu trúc trong bộ nhớ là toàn bộ các sâu khác có thể có). Đây vẫn là một hoạt động liên tục thời gian; chỉ cần hai bước thay vì một bước.
Bạn biết làm thế nào đĩa đĩa cứng quay xung quanh và xung quanh? Vâng, RAM không di chuyển ;-) –
Nó sẽ là không đổi nếu bạn ngay lập tức có thể nhảy đến nhà # 20. Đó là cách hoạt động của RAM. Truy cập ngẫu nhiên so với truy cập tuần tự. Trong trường hợp này, ngẫu nhiên có nghĩa là bạn có thể đọc từ bất kỳ vị trí bộ nhớ "ngẫu nhiên" nào mà không phải đọc bộ nhớ trước đó. Cũng vậy với văn bản. – SRM