Section 12.4 - Using Access Values

Once you have an access type, you can do all sorts of interesting things with it.

One common use of access types is to "walk" down a list of nodes to do something to each data item. A subprogram that examines each node in turn is sometimes called an iterator. Here's an example that prints in order the value of every node in a list of List_Nodes:

  -- Assume that "Start" accesses the first node in the list.
  Current := Start;  -- Set current to the start of the list.
  while Current /= null loop -- while there is data:
    Put(Current.Data);       -- Print the value of the Current node.
    Current := Current.Next; -- Go to the next node in the list.
  end loop;

You can have more complex data structures than the simple list we've had so far by storing more than one access value in a node. For example, a binary tree is a set of nodes, where each node has a way to locate its "parent" node, its "left child" node, and its "right child" node. Each node also has data it contains (for example, an Unbounded_String). Defining a record for a binary tree node using access values is easy:

  type Tree_Node; -- Incomplete type declaration.
  type Tree_Access is access Tree_Node;
  type Tree_Node is
    record
      Parent      : Tree_Access;
      Left, Right : Tree_Access;
      Data        : Unbounded_String;
    end record;

Here's an example of statements using this tree data structure, if A and B are of type Tree_Access:

  A := new Tree_Node;
  B := new Tree_Node;
  A.Data := To_Unbounded_String("Hello!");   -- assign some data
  B.Data := To_Unbounded_String("Goodbye!");
  A.Left := B;                               -- connect them.
  B.Parent := A;

If a data component is an access value, you can use it as you would any other access value. As a result, you can find statements with multiple dots (.) in them. For example, after running the program above, the value of A.Left.Data is "Goodbye!".

It's easy to incorrectly use access types and connect things the wrong way. Therefore, it's best to create subprograms that "do it correctly" and then use the subprograms instead. For example, you might create a subprogram that automatically creates new nodes, sets their data value, and connects them up to an existing node in the correct place. The best approach is to use pre-created reusable components that meet your needs if they're available.


Quiz:

In the tree data structure example above, what is the value of B.Parent.Data?

  1. An empty Unbounded_String.
  2. "Hello!" as an Unbounded_String.
  3. "Goodbye!" as an Unbounded_String.
  4. None; an exception would be raised.

You may also:

PREVIOUS Go back to the previous section

NEXT     Skip to the next section

OUTLINE  Go up to lesson 12 outline

David A. Wheeler (dwheeler@dwheeler.com)

The master copy of this file is at "http://www.adahome.com/Tutorials/Lovelace/s12s4.htm".