Reference (computer science): Difference between revisions
m fixing disambiguation format using AWB |
→Address analogy: Added a bt more clarity to the example |
||
Line 10: | Line 10: | ||
In a more complicated example, suppose you leave a forwarding address in your old house each time you move. A person could visit your first house, then follow the forwarding address to the next house, and so on until they finally find your current house. This is analogous to how references are used in singly [[linked list]]s. |
In a more complicated example, suppose you leave a forwarding address in your old house each time you move. A person could visit your first house, then follow the forwarding address to the next house, and so on until they finally find your current house. This is analogous to how references are used in singly [[linked list]]s. |
||
Another benefit of addresses is that they're much easier to deal with than actual houses. Say you want to be able to easily locate people on your street based on their last name. One way to do this is to rearrange all the houses based on the last names of the residents. A much easier solution is to make a list of addresses of people on your street and sort it by their last names. References have the same benefit: you can manipulate references to data without actually having to modify the data itself, which in some cases can be much more efficient. |
Another benefit of addresses is that they're much easier to deal with than actual houses. Say you want to be able to easily locate people on your street based on their last name. One way to do this is to use a large crane to physically pick up and rearrange all the houses based on the last names of the residents. A much easier solution is to make a list of addresses of people on your street and sort it by their last names. References have the same benefit: you can manipulate references to data without actually having to modify the data itself, which in some cases can be much more efficient. |
||
Other examples of references abound in everyday life: telephone numbers, e-mail addresses, [[Uniform Resource Locator|URL]]s, and so on. Each refers to and facilitates access to a remote resource. |
Other examples of references abound in everyday life: telephone numbers, e-mail addresses, [[Uniform Resource Locator|URL]]s, and so on. Each refers to and facilitates access to a remote resource. |
Revision as of 16:00, 31 March 2006
- This article discusses a general notion of reference in computing. See also the more specific notion of reference used in C++.
In computer science, a reference is a small object containing information which refers to data elsewhere, as opposed to containing the data itself. Accessing the value that a reference refers to is called dereferencing it. References are fundamental in constructing many data structures and in exchanging information between different parts of a program.
Address analogy
A reference may be compared to the address of a house. It is a small identifier which helps you to find a potentially much larger object with more information in it. For example, although looking at a house will tell you its color, the address will not; it only enables you to find it. However, if you want to find out the color of a house, the address is enough information, because you can use it to find the house, then look at the house itself. Finding a house based on its address is analogous to dereferencing a reference.
In a more complicated example, suppose you leave a forwarding address in your old house each time you move. A person could visit your first house, then follow the forwarding address to the next house, and so on until they finally find your current house. This is analogous to how references are used in singly linked lists.
Another benefit of addresses is that they're much easier to deal with than actual houses. Say you want to be able to easily locate people on your street based on their last name. One way to do this is to use a large crane to physically pick up and rearrange all the houses based on the last names of the residents. A much easier solution is to make a list of addresses of people on your street and sort it by their last names. References have the same benefit: you can manipulate references to data without actually having to modify the data itself, which in some cases can be much more efficient.
Other examples of references abound in everyday life: telephone numbers, e-mail addresses, URLs, and so on. Each refers to and facilitates access to a remote resource.
Benefits of references
References increase flexibility in where objects can be stored, how they are allocated, and how they are passed between areas of code. As long as we can access a reference to the data, we can access the data through it, and the data itself need not be moved. They also make sharing of data between different code areas easier; each keeps a reference to it.
The mechanism of references, if varying in implementation, is a fundamental programming language feature common to nearly all modern programming languages. Even some languages that support no direct use of references have some internal or implicit use. For example, the call by reference calling convention can be implemented with either explicit or implicit use of references.
Pointers are the most primitive and error-prone but also one of the most powerful and efficient types of references, storing only the address of an object in memory. Smart pointers are opaque data structures that act like pointers but can only be accessed through particular methods.
A file handle, or handle is a type of reference used to abstract file content. It usually represents both the file itself, as when requesting a lock on the file, and a specific position within the file's content, as when reading a file.
Formal representation
More generally, a reference can be considered as a piece of data that allows unique retrieval of another piece of data. This includes primary keys in databases and keys in an associative array. If we have a set of data D, any well-defined (single-valued) function from D onto D ∪ {null} defines a type of reference, where null is the image of a piece of data not referring to anything meaningful.
An alternative representation of such a function is a directed graph called a reachability graph. Here, each datum is represented by a vertex and there is an edge from u to v if the datum in u refers to the datum in v. The maximum out-degree is one. These graphs are valuable in garbage collection, where they can be used to separate accessible from inaccessible objects.
External and internal storage
In many data structures, large, complex objects are composed of smaller objects. These objects are typically stored in one of two ways:
- With internal storage, the contents of the smaller object are stored inside the larger object.
- With external storage, the smaller objects are allocated in their own location, and the larger object only stores references to them.
Internal storage is usually more efficient, because there is a space cost for the references and dynamic allocation metadata, and a time cost associated with dereferencing a reference and with allocating the memory for the smaller objects. Internal storage also enhances locality of reference by keeping different parts of the same large object close together in memory. However, there are a variety of situations in which external storage is preferred:
- If the data structure is recursive, meaning it may contain itself. This cannot be represented in the internal way.
- If the larger object is being stored in an area with limited space, such as the stack, then we can prevent running out of storage by storing large component objects in another memory region and referring to them using references.
- If the smaller objects may vary in size, it's often inconvenient or expensive to resize the larger object so that it can still contain them.
- References are often easier to work with and adapt better to new requirements.
Some languages, such as Java, do not support internal storage. In these languages, all objects are uniformly accessed through references.
Language support
In assembly languages, the first languages used, it is typical to express references using either raw memory addresses or indexes into tables. These work, but are somewhat tricky to use, because an address tells you nothing about the value it points to, not even how large it is or how to interpret it; such information is encoded in the program logic. The result is that misinterpretations can occur in incorrect programs, causing bewildering errors.
One of the earliest opaque references was that of the Lisp programming language cons cell, which is simply a record containing two references to other Lisp objects, including possibly other cons cells. This simple structure is most commonly used to build singly linked lists, but can also be used to build simple binary trees and so-called "dotted lists", which terminate not with a null reference but a value.
Another early language, Fortran, does not have an explicit representation of references, but does use them implicitly in its call-by-reference calling semantics.
The C programming language introduced the pointer, still one of the most popular types of references today. It is similar to the assembly representation of a raw address, except that it carries a static datatype which can be used at compile-time to ensure that the data it refers to is not misinterpreted. However, because C has a weak type system which can be violated using casts (explicit conversions between various pointer types and between pointer types and integers), misinterpretation is still possible, if more difficult. Its successor C++ tried to increase type safety of pointers with new cast operators and smart pointers in its standard library, but still retained the ability to circumvent these safety mechanisms for compatibility.
A number of popular mainstream languages today such as Java, C#, and Visual Basic have adopted a much more opaque type of reference, usually referred to as simply a reference. These references have types like C pointers indicating how to interpret the data they reference, but they are typesafe in that they cannot be interpreted as a raw address and unsafe conversions are not permitted. In those managed languages, the references are actually pointers of pointers of the referred data. In C/C++, the reference concept of managed languages means two-step pointing. The Garbage Collector is the sole actor that can directly access the mid-step pointers, which cause the opacity. Typically pointer arithmetic is also not supported.
Fortran
A Fortran reference is best thought of as an alias of another object, such as a scalar variable or a row or column of an array. There is no syntax to dereference the reference or manipulate the contents of the referent directly. Fortran references can be null. As in other languages, these references facilitate the processing of dynamic structures, such as linked lists, queues, and trees.
Functional languages
In all of the above settings, the concept of mutable variables, data that can be modified, often makes implicit use of references. In Standard ML, O'Caml, and many other functional languages, most values are persistent: they cannot be modified by assignment. Assignable "reference cells" serve the unavoidable purposes of mutable references in imperative languages, and make the capability to be modified explicit. Such reference cells can hold any value, and so are given the polymorphic type α ref
, where α
is to be replaced with the type of value pointed to. These mutable references can be pointed to different objects over their lifetime. For example, this permits building of circular data structures.
To preserve safety and efficient implementations, references cannot be type-cast in ML, nor can pointer arithmetic be performed. It is important to note that in the functional paradigm, many structures that would be represented using pointers in a language like C are represented using other facilities, such as the powerful algebraic datatype mechanism. The programmer is then able to enjoy certain properties (such as the guarantee of immutability) while programming, even though the compiler often uses machine pointers "under the hood".
See also
External links
- Pointer Fun With Binky Introduction to pointers in a 3 minute educational video - Stanford Computer Science Education Library