CSE 374, Lecture 12: Pointers + Structs

Pointer mystery

One of the problems on your midterm will be a pointer mystery exercise. You will be given a C program and be expected to determine its output. We went through an example problem (linked on the course website) and talked about techniques for approaching this kind of analysis. Some strategies:

Types we've seen in C

Typedef

One way to expand on the regular types in C is using something called "typedef" which allows you to give a different name to an existing type. This is kind of like an "alias" in bash. You can create a new typedef alias by using the "typedef" keyword, providing a normal type, and then giving it a new name. You can use the name throughout the rest of your program.

    typedef <type> <name>;

In C, strings are "char*", but if I wanted to actually provide the name "string", I could!

    typedef char* string;
    int main(int argc, string *argv) {
      string s = "hello, world!";
      printf("%s\n", s);
    }

Structs

The basic types that we've learned about aren't the only types in C! We can combine those simple types into a combination type called a "struct" that contains multiple simple types. For example, let's say that we want to create a type that represents a 2-dimensional point with an x-coordinate and a y-coordinate.

    struct Point {
      int x;
      int y;
    };

    int main(int argc, char **argv) {
      struct Point foo;
      foo.x = 4;
      foo.y = 5;
    }

When we define a struct, we refer to the things contained within it as "fields" just like in Java (x and y in this case). The name "Point" is what we call a "tag" which gives hints to the compiler. A TAG is NOT the same thing as a TYPE. When we create a new struct in the main function, we see that the full type is "struct Point" and not just "Point". However if we did want it to be named "Point" and not "struct Point", we can use a typedef to alias the name to the shorter version:

    typedef struct Point Point;

Now we can refer to just "Point" throughout the rest of our code! We could even declare the typedef at the same time as we declare the struct:

    typedef struct Piont {
      int x;
      int y;
    } Point;

In memory, structs are stored in a contiguous block of memory, kind of like an array, except you can store different types in a struct, such as a char* and an int.

       ------------     -
    x |            |     |
       ------------      |-- struct Point
    y |            |     |
       ------------     -

Let's write a function to create a new Point struct:

    Point newPoint() {
      Point p;
      p.x = 0;
      p.y = 0;
      return p;
    }

Notice how we refer to the fields of a struct: with the "." notation, as in "p.x".

Let's write a function to translate a point in the x dimension.

    void translateX(Point p, int deltaX) {
      p.x = p.x + deltaX;
    }

This won't work! Why won't it work? Remember that in C, all arguments to a function (and returns from a function) are COPIES of the original. This is true for structs as well. So if we pass a type Point into the function, it will create a copy of the entire struct and the function will modify the copy, not the original! That's not what we intended; we wanted to modify the original point. We can use pointers to get around this.

    void translateX(Point *p, int deltaX) {
      (*p).x = (*p).x + deltaX;
      // OR
      p->x = p->x + deltaX;
    }

Now, we're passing an ADDRESS to a point as a parameter instead of a copy of the point, so any modifications we make via the pointer will be in the original struct. We can dereference the pointer (*p) and then use the "." to get the x element. There's also a shortcut way to do this with the "->" which both dereferences the pointer (follows the address) and finds the field of the appropriate type.

C structs vs Java objects

How are C structs different from Java objects? C structs have no BEHAVIOR associated with them; they can't have member methods. Java classes on the other hand have constructors and behaviors that allow them to mutate their data.