- vừa được xem lúc

[Procedural Programming + Ada] Bài 9 - Recursive Record & Access Pointer

0 0 6

Người đăng: Semi Dev

Theo Viblo Asia

Trong bất kỳ môi trường lập trình nào thì cũng có những trường hợp ứng dụng nhất định mà chúng ta cần phải định nghĩa một cấu trúc dữ liệu Đệ Quy. Tức là trong code định nghĩa đang viết có sử dụng ngay tên của chính kiểu dữ liệu đó. Và ở đây chúng ta sẽ tìm hiểu về thao tác định nghĩa một cấu trúc như vậy trong Ada.

Recursive Record

Trong môi trường của C như đã biết - khi viết định nghĩa struct, chúng ta có thể sử dụng ngay tên của kiểu struct đang định nghĩa để định kiểu cho các trường dữ liệu bên trong nếu cần thiết. Tuy nhiên thông thường thì khi làm việc với các struct chúng ta sẽ sử dụng định kiểu dạng con trỏ và như vậy một struct đệ quy thường có dạng như thế này:

typedef struct node { void* data; struct node* next;
} node_struct;

Và ở đây trong Ada, để định nghĩa một record đệ quy thì chúng ta cũng có thể sử dụng ký thuật tương tự với sự hỗ trợ của khái niệm con trỏ access.

package Item is type Struct; -- early declaration type Pointer is access all Struct; type Struct is record Value: Integer; Next: Pointer; end record; private -- nothing here end Item;

Và khi sử dụng kiểu con trỏ access để làm tên định kiểu chính cho record giống như khi code C thì chúng ta có sẵn trình khởi tạo với cú pháp new vay mượn từ nhóm công cụ Lập Trình Hướng Đối Tượng Object-Oriented Programming. Cú pháp này sẽ tách lấy địa chỉ tham chiếu để trả về cho biến access lưu lại.

with Ada.Text_IO; use Ada.Text_IO;
with Item; use Item; procedure Main is Instance, Cursor : Item.Pointer;
begin Instance := new Item.Struct'(0, null); Instance := new Item.Struct'(1, Instance); Instance := new Item.Struct'(2, Instance); Instance := new Item.Struct'(3, Instance); Instance := new Item.Struct'(4, Instance); Instance := new Item.Struct'(5, Instance); Instance := new Item.Struct'(6, Instance); Instance := new Item.Struct'(7, Instance); Instance := new Item.Struct'(8, Instance); Instance := new Item.Struct'(9, Instance); -- move cursor from the first item and print the list Cursor := Instance; Put ("List : "); while Cursor /= null loop Put (Integer'Image (Cursor.Value) & " "); Cursor := Cursor.Next; end loop;
end Main;
List : 9 8 7 6 5 4 3 2 1 0

Dereference Access

Trong những trường hợp nhất định khi làm việc với các kiểu cấu trúc khác - không phải là mảng array hoặc record - thì chúng ta sẽ phải thực hiện thao tác chuyển kiểu trong code. Thao tác truy xuất tổng bộ nội dung của một access và gán trả về một biến thuộc kiểu dữ liệu nguyên bản được gọi là dereference và được thực hiện thông qua khóa all của con trỏ access như sau:

Pointer : Item_Access := new Item'( Value => 1, Next_Access => null );
Origin : Item := Pointer.all;

Ở chiều ngược lại, khi chúng ta muốn tách lấy địa chỉ từ một biến thông thường lưu trữ array hoặc record để gán vào một biến con trỏ access thì chúng ta cần đảm bảo các điều kiện là:

  • Phải tạo một biến cục bộ local của sub-program được khai báo với từ khóa aliased ở phía trước tên định kiểu.
  • Biến con trỏ access cũng phải được khai báo cục bộ đối với sub-program.

Các điều kiện này là để đảm bảo rằng, thao tác chuyển kiểu từ giá trị Value sang kiểu địa chỉ Access cần được kiểm soát trong phạm vi cục bộ của từng sub-program. Đây là một dạng thiết kế an toàn mà Ada tạo ra để đảm bảo việc sử dụng kiến trúc con trỏ access phải được kiểm soát chặt chẽ trong logic nội tại của người viết code.

Sau đó thao tác tách lấy địa chỉ tham chiếu và gán vào biến con trỏ access sẽ có thể thực hiện được nhờ thuộc tính Value'Access.

Value : aliased Item;
Pointer : Item_Access;
Pointer := Value'Access;

Mặc dù vẫn còn rất nhiều thứ để nói về record trong Ada tuy nhiên chúng ta sẽ để dành cho một Sub-Series khác nói về tư duy Lập Trình Hướng Đối Tượng. Ở đây chúng ta sẽ chuyển sang tìm hiểu những công cụ phổ biến khác mà Ada cung cấp cho môi trường lập trình phổ thông (không bao gồm embedded).

[Procedural Programming + Ada] Bài 10 - Overloading Sub-program & Generics

Bình luận

Bài viết tương tự

- vừa được xem lúc

Closure trong Javascript - Phần 2: Định nghĩa và cách dùng

Các bạn có thể đọc qua phần 1 ở đây. Để mọi người không quên, mình xin tóm tắt gọn lại khái niệm lexical environment:.

0 0 51

- vừa được xem lúc

Var vs let vs const? Các cách khai báo biến và hằng trong Javascript

Dạo này mình tập tành học Javascript, thấy có 2 cách khai báo biến khác nhau nên đã tìm tòi sự khác biệt. Nay xin đăng lên đây để mọi người đọc xong hy vọng phân biệt được giữa let và var, và sau đó là khai báo hằng bằng const.

0 0 31

- vừa được xem lúc

VueJS: Tính năng Mixins

Chào mọi người, hôm nay mình sẽ viết về Mixins và 1 số vấn đề trong sử dụng Mixins hay ho mà mình gặp trong dự án thực. Trích dẫn từ trang chủ của VueJS:.

0 0 27

- vừa được xem lúc

Asset Pipeline là cái chi chi?

Asset Pipeline. Asset pipeline là cái chi chi. . Giải thích:.

0 0 47

- vừa được xem lúc

Tạo data table web app lấy dữ liệu từ Google Sheets sử dụng Apps Script

Google Sheets là công cụ tuyệt vời để lưu trữ bảng tính trực tuyến, bạn có thể truy cập bảng tính bất kỳ lúc nào ở bất kỳ đâu và luôn sẵn sàng để chia sẻ với người khác. Bài này gồm 2 phần.

0 0 266

- vừa được xem lúc

Học Deep Learning trên Coursera miễn phí

Bạn muốn bắt đầu với Deep Learning nhưng không biết bắt đầu từ đâu? Bạn muốn có một công việc ở mức fresher về Deep Learning? Bạn muốn khoe bạn bè về kiến thức Deep Learning của mình. Bắt đầu từ đâu.

0 0 35