************* BACK AND FORTH PAGING SUBROUTINE ************

PAGEFLOP

If they want to quit, do so
 If They want to quit subsession, Do SO!
  Decrement LOCAL and GLOBAL Page Counters

FORWARD

  Increment LOCAL and GLOBAL Page Counters
   *************** END PAGEFLOP *********************
  ****** CHAPTER INTERNAL SELECTOR ALGORITHM ******

SELECTOR

   Reset Local Page Counter

SELAGAIN

 CHECK IF ONLY A <CR>

WRONGSEL

YOUR SELECTION IS NOT IN THE 0 - #SELIMIT  RANGE  Please try again

SELRTRN

    <<<<<< REVIEW CLEANING SUBROUTINE >>>>>>

PAUSE

If they want to quit, do so

AANVANG

Copyright CourseWare Technologies Inc., 1985-88


Lesson - 7


 POINTERS IN C 

P0

Pointers|Topics to Learn|7-0|11,52
  #                    Topic
 ---                  -------
  1   -   Pointers in C
  2   -   Initializing Pointers
  3   -   Performing Pointer Operations
  4   -   Using Pointers as Function Arguments
  5   -   Using Arrays and Pointers
  6   -   Performing Pointer Arithmetic
  7   -   How Pointers Relate to Character Strings
  8   -   Lesson Review
  0   -   Return to the Main Menu

P1

Pointers|Pointers in C|7-1.1|11,54
     A pointer is a variable that holds the 
address of another variable.


     Pointers are type bound,, i.e., pointers must 
be declared with the type of data objects that they 
may point to.


     In the declaration, the pointer variables must 
be preceded with an asterisk (*).

P2

Pointers|Pointers in C|7-1.2|7,56
In the following example, the variable int_ptr is a 
pointer to a variable, that is, it can hold an address
of a variable of type int.  The variable char_ptr is a
pointer to a variable of type char which may be a single
character or a character string.  The variable float_ptr 
is a pointer to a variable of type float.  The pointer 
array names may point to NAME_NUM variables of type char.

P3

Pointers|Pointers in C|7-1.3|8,50
int    *int_ptr;     /* a pointer to an integer */
char   *char_ptr;   /* a pointer to a character */
float  *float_ptr;  /* a pointer to a float     */
char   *names[NAME_NUM]; /* NAME_NUM pointers to
                characters or character strings */

 Do you want to see an illustration? (y/n):  
                   ILLUSTRATION                       

 Given the memory space on the computer
 system illustrated on the left ...
           Memory Space
     0    -------------
     :   |             |
     :    -------------
   13777 |             |
     :    -------------
     :   |             |
        -------------
   22625 |             |
     :    -------------
     :          :
     :    -------------
   45724 |             |
     :    -------------
     :   |             |
   512K   -------------

 and given the variables:
      int volume, volume2, *vol_ptr;
 which occupy locations shown on the left,
 volume
 volume2
 vol_ptr
 when the assignment "volume = 15"
 is performed, the result is
 store 15 in "volume".
 15
 15
 After we assign the address
 of "volume" to "vol_ptr",
     vol_ptr = &volume;  
 the result is as illustrated.
 13777
 13777
    <<<<<< CLEAR THE MESSAGE SPACE >>>>>>

ENCORE2

 FINALLY DO THE LAST PROMPT
 An assignment "volume2 = *vol_ptr"
 results in 15 being assigned to
 volume2.
 15

P4

Pointers|Initializing Pointers|7-2.1|18,56
     A pointer must point to an object before it can be
used.  This is done with the unary operator  &  which 
gives the address of the object, rather than its value.  
For example,
    int volume, volume2, *vol_ptr;

To assign the address of volume to vol_ptr use:

vol_ptr = &volume;

To assign to volume2 the value vol_ptr is pointing to use:

volume2 = *vol_ptr;


     Placing an  *  in front of a pointer variable 
gives the value of the object that the pointer is 
pointing to.

P5

Pointers|Performing Pointer Operations|7-3.1|10,54
     The unary operators  *  and  &  bind more
tightly than arithmetic operators, thus when in 
doubt, use parentheses.


The following example demonstrates pointer variables 
used in arithmetic expressions or pointer arithmetic.
Note that we have declared three variables.  v1 and 
v2 are explicit variables of type int and *v_ptr 
is a pointer variable of type int.

P6

Pointers|Performing Pointer Operations|7-3.2|14,56
int v1, v2, *v_ptr;                  /* declarations */

v1 = v2 * (*v_ptr);      /* multiply v2 by the value
                                 pointed to by v_ptr */
v2 = v1 + *v_ptr + 7; /* add v1 to the value pointed
                               to by v_ptr and add 7 */
v2 = *(v_ptr + 3);   /* assign to v2 the value which
                    is 3 integers beyond where v_ptr
                                      is pointing to */
*v_ptr = 0;    /* zero the value pointed to by v_ptr */
*v_ptr++ = 0;         /* zero the pointed to object,
                             and advance the pointer */
*(++v_ptr) = 0;        /* advance the pointer to the
                 next object and set the object to 0 */

P7

Pointers|Pointers as Function Arguments|7-4.1|14,50
     By specifying the argument as a pointer to an 
object of a particular type, one is coercing a 
function to pass the address of that object rather
than its value.  This method of argument passing 
is referred to as call by reference.


The following program:

(1) accepts a line of input from the keyboard, 
(2) counts the number of times numerics (the characters
    '0' - '9') occur in the line of input, and
(3) displays the line and the number of times numeric 
     characters occur.

P8

Pointers|Pointers as Function Arguments|7-4.2|14,53
/* The code for the main() program/function */

#define     LINE_LEN   80 /*  maximum line length  */
main()
{
     char line[LINE_LEN + 1];    /* line buffer  */
     int number;

     printf("Enter new line of text.\n_>");
     read_line(line, LINE_LEN);
     digit_count(line, &number);
     printf("\nIn the line \n%s\ndigits",line);
     printf(" 0-9 occur %d times\n", number);
}

P9

Pointers|Pointers as Function Arguments|7-4.3|15,48
  /*  The function read_line reads a string
      text from the terminal until newline or
      end of file characters are encountered  */

read_line(s, max)
    char s[];              /* same as *string */
    int max;  /* maximum number of characters */
{
    int i=0, c;

    while ((c = getchar()) != '\n' &&
            c != EOF && i < max)
        s[i++] = c;  /* save char. adv. index */
    s[i] = '\0';    /* char. string terminate */
}

P10

Pointers|Pointers as Function Arguments|7-4.4|16,54
/* This function calculates the number of occurrences 
   of digits, i.e., characters 0-9, in the string(s) */

digit_count(s, times)
    char s[];           /* address of the array s[]  */
    int *times;
{
    int i=0;
    *times = 0;        /* initially zero occurrences */

    for (; s[i++] ;)  /* same as while (s[i++] != 0) */
        if ((s[i] >= '0') && (s[i] <= '9'))
            (*times)++;   /* increment the number of
                                         occurrences */
}

P11

Pointers|Using Arrays and Pointers|7-5.1| 18 , 49
     Any operation that can be achieved by array 
subscripting can also be achieved by using pointers.

     int ar[10], *ar_ptr, intv;                
     ar_ptr = &ar[0] IS EQUIVALENT TO ar_ptr = ar ;
     intv = *ar_ptr;                            


     Whenever a number is added to or subtracted from 
a pointer, that number is scaled by the size of the 
object that the pointer is pointing to.


     Pointing to a nonexistent element will produce 
run-time errors, usually with the message "Memory Fault".

P12

Pointers|Performing Pointer Arithmetic|7-6.1|17,56
int *int_ptr, v_int, ar[10];   /* integer is 16 bits */
char *char_ptr, v_char;       /* character is 8 bits */
float *float_ptr, v_float;       /* float is 64 bits */

v_int = *(int_ptr + 5);   /* will point to the value
               of the 2 byte element 10 bytes beyond
                  where int_ptr is currently pointing */

v_float = *(int_ptr++ + 5);  /* will perform the same
                operation as above, plus it will move
                          the int_ptr 2 bytes further */

v_float = *(--float_ptr - 5); /* will move the float_ptr
                 one float size (8 bytes) back, then will
                 point to value 5 float sizes before the
                  pointer position and assign this value
                 to v_float;                         */

P13

Pointers|Performing Pointer Arithmetic|7-6.2|12,56
/*   Using the variables from the previous example:  */

*int_ptr = ar[7]; <==> *int_ptr = *(ar + 7);
                     /* will assign the value of the
                        8th element of the string ar
                       to the object that int_ptr is
                                         pointing to */

v_int = int_ptr[4]; <==> v_int = *(int_ptr + 4);
                    /* shows that pointers may be
                       used with subscripts as
                             well as with asterisks. */

P14

Pointers|Performing Pointer Arithmetic|7-6.3|10,56
Note that a pointer is a variable while an array name is 
a constant, therefore expressions which assign a pointer 
to an array, increment an array name, or take the address 
of an array are illegal. 

You  may not:

ar++;                 but you may      int_ptr++;
ar++;                 but you may      int_ptr++;
int_ptr = &ar;        but you may      int_ptr = &ar[i];

P15

Pointers|Pointers and Character Strings|7-7.1|14,54
     If a character string is a function argument, 
it may be equivalently declared as:

char *s;  OR  char s[];

The following example shows a pointer version of the 
function str_upper() which converts a character string 
to uppercase.  Note that the algorithm is the same as
in the array version of the same function, which you 
saw earlier.  On the other hand, here we are not using 
array subscripts to access values, but rather the 
character pointer  * .  Note how the pointer variable
is advanced and that the terminating condition is the
character NULL.

P16

Pointers|Pointers and Character Strings|7-7.2|9,43
str_upper(s)        /* convert to upper, */
    char *s;        /*  pointer version  */
{
    while (*s) {
        if (*s >= 'a' && *s <= 'z')
            *s = *s + 'A' - 'a';
        s++;
    }
}

P17

Pointers|Pointers and Character Strings|7-7.3|10,43
     A pointer to a character string may be 
initialized if it is either an internal or an 
external variable.  For example:

char *string = "warning";


     Arrays and arrays of pointers to character 
strings may be initialized only if they are 
external.

P18

Pointers|Pointers and Character Strings|7-7.4|11,51
The following example shows various initialization 
capabilities for both arrays and pointer variables.  
Note that explicit arrays as well as arrays of pointers 
can be initialized only if they are external.  On the 
other hand, if the variable string1 were declared as 
char, it could have been initialized inside the 
function as well.  Furthermore, the internal variable 
string2 could have been declared and initialized 
externally.  To better convince yourself or make some 
additional test cases, try running this program on your 
system.

P19

Pointers|Pointers and Character Strings|7-7.5|18,56
int dum_arr[] = {5, 4, 3, 2};
char char_arr[4] = { 'a', 'b', 'C', 'd'};
char *str_ar[]  =  {"CCCCCCCC", "NNNNNNNN", "VVVVVVVV"};
char string1[] = "7777777";
main()
{   int i;  char *string2 = "XXXXXXXX";
    for (i=0; i <= 3; i++)
        printf("The %dth value of the array is %d\n",
                i, dum_arr[i]);
    for (i=0; i <= 3; i++)
        printf("The %dth value of  ch_array is %c\n",i,
                 char_arr[i]);
    for (i = 0; i <= 2; i++)
        printf("The %dth value of   str_ar is %s\n",
                i, str_ar[i]);
    printf("STRING1 = %s, STRING2 = %s\n", string1,
                string2);
}

P20

Pointers|Pointers and Character Strings|7-7.6|14,39
Results produced by the above program.

  The 0th value of the array is 5
  The 1th value of the array is 4
  The 2th value of the array is 3
  The 3th value of the array is 2
  The 0th value of  ch_array is a
  The 1th value of  ch_array is b
  The 2th value of  ch_array is C
  The 3th value of  ch_array is d
  The 0th value of   str_ar is CCCCCCCC
  The 1th value of   str_ar is NNNNNNNN
  The 2th value of   str_ar is VVVVVVVV
  STRING1 = 7777777, STRING2 = XXXXXXXX