Pointers are variables that contain the memory addresses of objects or functions. Pointer variables are declared as a pointer type by using the asterisk punctuator and the data type of the object pointed to, as shown in the following syntax:
* type-qualifier-list(opt) * type-qualifier-list(opt) pointer
type-qualifier type-qualifier-list type-qualifier
By default, DEC C pointers are 32 bits long on
OpenVMS systems and 64 bits long on Digital UNIX systems. Although
their defaults are different, both OpenVMS Alpha and Digital UNIX
systems support 32-bit (short) and 64-bit (long) pointers. DEC C
provides qualifiers/switches and #pragma
preprocessor
directives to control pointer size.
The type-qualifier is either const
,
volatile
, __unaligned
(Alpha), __restrict
, or any
combination thereof.
An object of pointer type is declared as in the following example:
char *px;
In this example, identifier px
is declared as a pointer
to an object of type char
. No type-qualifier is
used in this example. The expression *px
yields the
char
that px
points to.
The following declarations show the difference between a variable pointer to a constant, a constant pointer to a variable, and a constant pointer to a constant object.
const int *ptr_to_constant; /* pointer variable pointing to a const object */ int *const constant_ptr; /* constant pointer to a non-const object */ const int *const constant_ptr; /* Const pointer to a const object */
The contents of an object pointed to by ptr_to_constant
cannot be modified through that pointer, but ptr_to_
constant
itself can be changed to point to another
const
-qualified object. Similarly, the contents of
the integer pointed to by constant_ptr
can be modified,
but constant_ptr
itself will always point to the same
location.
The declaration of the constant pointer constant_ptr
can be clarified by including a definition for the type pointer to
int
. The following example declares constant_
ptr
as an object with type const-qualified pointer
to int
. The pointer's value (an address) is constant:
typedef int *int_ptr; const int_ptr constant_ptr;
The __unaligned
data-type qualifier can be used
in pointer definitions on Alpha systems. to indicate to the
compiler that the data pointed to is not properly aligned on a
correct address. (To be properly aligned, the address of an object
must be a multiple of the size of the type. For example, 2-byte
objects must be aligned on even addresses.)
(Alpha)
When data is accessed through a pointer declared
__unaligned
, the compiler generates the additional
code necessary to copy or store the data without causing alignment
errors. It is best to avoid use of misaligned data altogether,
but in some cases the usage may be justified by the need to access
packed structures, or by other considerations.
(Alpha)
The __restrict
data-type qualifier is used to
designate a pointer as pointing to a distinct object, thus allowing
compiler optimizations to be made (see Section 3.7.4).
Unless an extern
or static
pointer
variable is explicitly initialized, it is initialized to a null
pointer. A null pointer is a pointer value of 0. The contents of an
uninitialized auto
pointer are undefined.
A void
pointer is a pointer without a specified data
type to describe the object to which it points. In effect, it is
a generic pointer. (Before the ANSI C standard, char
* was used to define generic pointers; this practice is now
discouraged by the ANSI standard because it is less portable.)
A pointer to any type can be assigned to a void
pointer without a cast, and vice versa. See Section 6.4.6 for more information on the cast operation. The
following statements show how a void
pointer can be
assigned to other typed pointers, without explicit casts:
float *float_pointer; void *void_pointer; . . . float_pointer = void_pointer; /* or, */ void_pointer = float_pointer;
A void
pointer is often used in function calls,
function arguments, or function prototypes when a parameter or
return value is a pointer of an unknown type. Consider the following
example, where a void
pointer is used as a generic
return value:
void *memcpy (void *s1, const void *s2, size_t n); { void *generic_pointer; . . . /* The function return value can be a pointer to many types. */ generic_pointer = func_returning_pointer( arg1, arg2, arg3 ); . . . /* size_t is a defined type */ }
See Section 5.3 for further
information about using void
in function declarations.
The pointer object can be initialized with a single expression. For example:
int i = 10; int *p = &i; /* p is a pointer to int, initialized */ /* as holding the address of i */
Without an initializer, the values of static
and
extern
pointers are automatically initialized to null
pointers (pointers to memory location 0).
The following declaration defines p
with type pointer
to char
, and initializes p
to point to
an object of type array of char
with length 4, whose
elements are initialized by a character string literal. (The null
character is the fourth member of the array.) If an attempt is
made to use p
to modify the contents of the array,
the behavior is undefined.
char *p = "abc";