4.6 Declaring Pointers

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:

pointer:

   * type-qualifier-list(opt) 
   * type-qualifier-list(opt) pointer 

type-qualifier-list:

   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.

4.6.1 Declaring void Pointers

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.

4.6.2 Initializing Pointers

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";


Previous Page | Next Page | Table of Contents | Index