Partial lecture notes from Wed. Feb 6

Lots of students were prevented from coming to class by our snowstorm. I hope that these notes help you a little bit. Also check with other students who did make it to class and took notes.
Karen


Allowed Operations on Pointers


  int *px, *py;
  int x, y;

  px = &x;  /* get address */
  py = &y;

  px = py;  /* assignment */
            /* both lhs and rhs are same type */

  px = NULL;  /* assignment to NULL */

  if ( px == NULL)    /* comparison */
    printf("pointer is NULL\n");

NOT Allowed on Pointers


  int *px, *py, *pz;

  px = 12;  /* assignment to non-NULL literal */

  pz = px + py;  /* add or subtract of */
                 /* two pointer values */

  px = py * 2;   /* multiply or divide of */
                 /* pointer value(s) */

Draw a Diagram:


  int x, y, z;
  int *px, *py, *pz;

  px = &x;
  py = &y;
  pz = &z;

  *px = 24;

  py = px;

  z = 25;

  *py = x - z;
(Karen's start to a diagram)

    ---       ---
 x |   |     |   | px
    ---       ---

    ---       ---
 y |   |     |   | py
    ---       ---

    ---       ---
 z |   |     |   | pz
    ---       ---


Arrays

                .
            |   .    |
            |--------|
          / |        |  base
         /  |--------|
        |   |        |  base + (1 * size)
        |   |--------|
  array |   |        |  base + (2 * size)
 (one   |   |--------|
element |   |        |  base + (3 * size)
 per    |   |--------|
 box)       |   .    |
                .
.



      0   1   2   3   4     (index)
    ---------------------
    |   |   |   |   |   |
    |   |   |   |   |   |
    ---------------------

How this array is filled in in later class examples.



      0   1   2   3   4     (index)
    ---------------------
    | 1 | 2 | 3 | 4 | 5 |
    ---------------------

Declare:

   int  a[5];

Use:

   a[0] = 1;
   a[1] = 2;


As allocated within memory:

(one integer fits into a box)

                .
            |   .    |
            |--------|
          / |        |  a
         /  |--------|
        |   |        |  
        |   |--------|
        |   |        |  
        |   |--------|
        |   |        |  
         \  |--------|
          \ |        |  
            |--------|
            |   .    |
                .

Again, what memory (this array) looks like when filled in.

                .
            |   .    |
            |--------|
          / |   1    |  a
         /  |--------|
        |   |   2    |  
        |   |--------|
        |   |   3    |  
        |   |--------|
        |   |   4    |  
         \  |--------|
          \ |   5    |  
            |--------|
            |   .    |
                .


C uses pointer notation with arrays:


a[i] is equivalent to *(a + i)

and

&(a + i) is equivalent to a + i

This is the most important slide to understand!



   int  a[5];
   int  *ap;


   ap = a;

   ap++;    /* ap has the address of a[1] */

   *ap = 2;


   ap++;    /* OK. */

   a++;    /* BAD! NOT ALLOWED! */
           /* a is a label, not a pointer! */


     #include <stdio.h>

     # define MAXARRAYSIZE 5
     main()
     {
        int intarray[MAXARRAYSIZE];
        int *iap;   /* a pointer to an int */
        int k;      /* loop induction variable */

        /* one implementation */
        /* notice the use of pointers and pointer arithmetic! */
        iap = intarray;
        for ( k = 0; k < MAXARRAYSIZE; k++) {
            *iap = k + 1;
            iap++;
        }
        iap = intarray;
        for ( k = 0; k < MAXARRAYSIZE; k++) {
            printf("%d\n", *iap);
            iap++;
        }

        /* another implementation */
        for ( k = 0; k < MAXARRAYSIZE; k++) {
            intarray[k] = k + 1;
        }
        for ( k = 0; k < MAXARRAYSIZE; k++) {
            printf("%d\n", intarray[k]);
        }
     }


From the lecture notes:

   int  a = 3;
   int  b = 8;
   int  c = 0;
   int  *cp;

   c = a + b;

   cp = &c;

   cp++;  /* allowed, but probably 
             not reasonable */

Contrast this code with:

   iap = intarray;
   for ( k = 0; k < MAX; k++) {
      . 
      . 
      iap++;  /* correct and reasonable? */
   }


C does not do any sort of
bounds checking!

   int  ar[12];

   ar[12] = -1;  /* No compiler error! */

   ar[300] = ar[300] + 3;  /* OK! */

This leads to the question:
Why no bounds checking?



 #include <stdio.h>

 void increment (int  a);

 main() {
   int x;

   x = 1;
   printf("before call, x = %d\n", x);
   increment( x);
   printf("after  call, x = %d\n", x);
 }

 void increment(int  a) {
   a++;
 }

Some explanation of this slide:

This program prints

before call, x = 1
before call, x = 1

The reason for this output is that C implements only call by value parameter passing.

If we wanted the increment function to increment x, then the main program must pass a pointer to x, rather than a copy of x. Here's the code to do that, with underlines showing items that changed in the code:

 #include <stdio.h>

 void increment (int *a);

 main() {
   int x;

   x = 1;
   printf("before call, x = %d\n", x);
   increment(& x);
   printf("after  call, x = %d\n", x);
 }

 void increment(int *a) {
   (*a)++;
 }


    int main() {
         
        x = a();
    }


    int a (){
         
        y = b();
    }


    int b (){
         
        z = c();
    }


    int c (){
         
    }

main calls a
a calls b
b calls c

c returns to b
b returns to a
a returns to main

The call tree for this code:

     main

      |
     \ /

      a

      |
     \ /

      b

      |
     \ /

      c