ppooiinntteerr -- C Language

A _p_o_i_n_t_e_r is  an object whose value is the  address of another object.  The
name  ``pointer'' derives  from  the fact  that its  contents ``point  to''
another object.   A pointer may point to any  type, complete or incomplete,
including another pointer.  It may also point to a function, or to nowhere.

The term  _p_o_i_n_t_e_r _t_y_p_e refers  to the object  of a pointer.   The object to
which a pointer points is called the _r_e_f_e_r_e_n_c_e_d _t_y_p_e. For example, an iinntt *
(``pointer  to  iinntt'') is  a  pointer  type; the  referenced  type is  iinntt.
Constructing a  pointer type from a referenced type  is called _p_o_i_n_t_e_r _t_y_p_e
_d_e_r_i_v_a_t_i_o_n.

_T_h_e _N_u_l_l _P_o_i_n_t_e_r
A pointer that  points to nowhere is a _n_u_l_l  _p_o_i_n_t_e_r. The macro NNUULLLL, which
is  defined in  the header  ssttddiioo.hh,  defines the  null pointer.   The null
pointer is an integer constant with the value zero.  It compares unequal to
a pointer to any object or function.

_D_e_c_l_a_r_i_n_g _a _P_o_i_n_t_e_r
To declare  a pointer, use the indirection operator  `*'.  For example, the
declaration

    int *pointer;

declares  that the  variable  ppooiinntteerr holds  the address  of an  iinntt-length
object.  Likewise, the declaration

    int **pointer;

declares that  ppooiinntteerr holds  the address of  a pointer whose  contents, in
turn, point to an iinntt-length object.

Failure to  declare a function that  returns a pointer will  result in that
function being implicitly declared as an  iinntt. This will not cause an error
on  microprocessors in  which an  iinntt  and a  pointer have  the same  size;
however,  transporting  this  code to  a  microprocessor  in  which an  iinntt
consists of  16 bits and a  pointer consists of 32 bits  will result in the
pointers being truncated to 16 bits and the program probably failing.

C allows  pointers and integers to  be compared or converted  to each other
without restriction.   The COHERENT C compiler  flags such conversions with
the strict message

    integer pointer pun

and comparisons with the strict message

    integer pointer comparison

These problems should be corrected if  you want your code to be portable to
other computing environments.

See CC llaanngguuaaggee for more information.

_W_i_l_d _P_o_i_n_t_e_r_s
Pointers are omnipresent in C.  C  also allows you to use a pointer to read
or write  the object to  which the pointer  points; this is  called _p_o_i_n_t_e_r
_d_e_r_e_f_e_r_e_n_c_i_n_g. Because  a pointer can point to any  place within memory, it
is possible to write  C code that generates unpredictable results, corrupts
itself, or even obliterates  the operating system if running in unprotected
mode.  A pointer that aims where it ought not is called a _w_i_l_d _p_o_i_n_t_e_r.

When a  program declares a  pointer, space is  set aside in  memory for it.
However, this space has not yet  been filled with the address of an object.
To fill  a pointer  with the address  of the object  you wish to  access is
called _i_n_i_t_i_a_l_i_z_i_n_g  it.  A wild pointer,  as often as not,  is one that is
not properly initialized.

Normally,  to initialize  a  pointer means  to  fill it  with a  meaningful
address.  For example, the following initializes a pointer:

    int number;
    int *pointer;
       . . .
    pointer = &number;

The address operator  `&' specifies that you want the  address of an object
rather  than its  contents.  Thus,  ppooiinntteerr is filled  with the  address of
nnuummbbeerr, and it can now be used to access the contents of nnuummbbeerr.

The   initialization  of   a  string   is   somewhat  different   than  the
initialization of a pointer to an integer object.  For example,

    char *string = "This is a string."

declares that  ssttrriinngg is  a pointer  to a cchhaarr.  It then stores  the string
literal TThhiiss iiss aa ssttrriinngg in memory and fills ssttrriinngg with the address of its
first  character.  ssttrriinngg  can then  be passed to  functions to  access the
string, or you can step through the string by incrementing ssttrriinngg until its
contents point to the null character at the end of the string.

Another way to initialize a pointer  is to fill it with a value returned by
a function that returns a pointer.  For example, the code

    extern char *malloc(size_t variable);
    char *example;
       . . .
    example = malloc(50);

uses the  function mmaalllloocc to allocate  50 bytes of dynamic  memory and then
initializes eexxaammppllee to the address that mmaalllloocc returns.

_R_e_a_d_i_n_g _W_h_a_t _a _P_o_i_n_t_e_r _P_o_i_n_t_s _T_o
The indirection  operator `*'  can be  used to read  the object to  which a
pointer points.  For example,

    int number;
    int *pointer;
       . . .
    pointer = &number;
       . . .
    printf("%d\n", *pointer);

uses ppooiinntteerr to access the contents of nnuummbbeerr.

When a pointer points to a structure, the elements within the structure can
be read  by using the  structure offset operator  `->'.  See the  entry for
ooppeerraattoorrss for more information.

_P_o_i_n_t_e_r_s _t_o _F_u_n_c_t_i_o_n_s
A pointer can also contain the address of a function.  For example,

    char *(*example)();

declares eexxaammppllee to be a pointer  to a function that returns a pointer to a
cchhaarr.

This declaration is quite different from:

    char **different();

The latter declares that ddiiffffeerreenntt is  a function that returns a pointer to
a pointer to a cchhaarr.

The following demonstrates how to call a function via a pointer:

    (*example)(_a_r_g_1, _a_r_g_2);

Here, the `*' takes the contents  of the pointer, which in this case is the
address of  the function, and uses  that address to pass  to a function its
list of arguments.

A pointer to  a function can be passed as  an argument to another function.
The functions  bbsseeaarrcchh and qqssoorrtt both take  function pointers as arguments.
A program may also use arrays of pointers to functions.

_P_o_i_n_t_e_r _C_o_n_v_e_r_s_i_o_n
One type of pointer may be  converted, or _c_a_s_t, to another.  For example, a
pointer to a cchhaarr may be cast to a pointer to an iinntt, and vice versa.

Pointers to different data types are compatible in expressions, but only if
they  are  cast  appropriately.   Using  them  without casting  produces  a
_p_o_i_n_t_e_r-_t_y_p_e _m_i_s_m_a_t_c_h.

_P_o_i_n_t_e_r _A_r_i_t_h_m_e_t_i_c
Arithmetic may be performed on all pointers to scalar types, i.e., pointers
to cchhaarrs or  iinntt.  Pointer arithmetic is quite limited  and consists of the
following:

11. One pointer may be subtracted from another.

22. An iinntt or a lloonngg, either variable or constant, may be added to a pointer
   or subtracted from it.

33. The operators ++ or -- may be used to increment or decrement a pointer.

No other  pointer arithmetic is permitted.  No  arithmetic can be performed
on pointers to non-scalar objects, e.g., pointers to functions.

When an  iinntt or lloonngg is  added to a pointer, it is  first multiplied by the
length of what the pointer is  declared as pointing to.  Thus, if a pointer
to an iinntt is incremented by two, it points down two more iinntts, not two more
characters.  The following program demonstrates this feature:

char *pc = "Welcome";
int array[5] = { 1, 2, 3, 4, 5 };
int  *pi = array;

main()
{
     pc += 2;  /* pc points to  'l' */
     pi += 2;  /* pi points to 3 */
}

_S_e_e _A_l_s_o
CC llaanngguuaaggee ddaattaa ffoorrmmaattss, ooppeerraattoorrss, ppoorrttaabbiilliittyy, PPrrooggrraammmmiinngg CCOOHHEERREENNTT
ANSI Standard,  section 6.1.2.5, section 6.2.2.1,  section 6.2.2.3, section
6.3.2.2-3, section 6.5.4.1
