structs

Here are some notes on structs in C.
Contents:

Introduction to structs

A struct is an aggregate data type, like an array.

However, an array has a certain regularity which a struct does not have. An array is an array of some number of something, all the same. E.g. an array of 100 ints. Each array member is an int. You can index which of the 100 ints you want to refer to with an arbitrary expression. This is only possible because all of the elements are the same size and are in order. This observation is similar to the statement that array indexing is pointer arithmetic.

A struct, on the other hand, is an aggregate in which the elements can be all different. They are referred to by name, and there is no analogue of an non-constant expression for an index.

Example: ordered pairs representing points in a plane.

struct point {
    int x, y;
};

"point" is the "struct tag". Altogether the above declares a type which we can call "struct point". It does not declare any objects (variables).

We can later say

struct point topleft, bottomright;
to define a rectangle perpendicular to the axes.

Here we use some structs as parameters, after the above type declaration:

double dist(struct point a, struct point b)
{
    double xdist = a.x - b.x;
    double ydist = a.y - b.y;
    return sqrt(xdist * xdist + ydist * ydist);
}

Struct "members" are accessed by saying the struct variable name, a dot, and then the member of the struct.

You may notice that this looks a lot like a class declaration. In fact structs are basically data-only classes (no "methods"). The "class" syntax in C++ (and subsequently in java) was derived from the C "struct" syntax.

However, a C struct, unlike a java class reference, is the data, not a reference to it. For example, in java, if you have an object of type "point" similar to the above, in which a.x is 3,

because the "b=a" assignment copies the reference.

Whereas in C, if you have an object of type "struct point" as above, in which a.x is 3,

because the "b=a" assignment copies the data, not a reference (pointer) to the data.

That is, "struct point a;" actually allocates space for the data. The analogue in C of java's "point a;" would be "struct point *a;", to allocate a pointer to a struct point, rather than to allocate a struct point itself.

Similarly, if you pass a struct to a function and the function modifies some struct members, it is modifying a copy, not the original. As with all parameter passing, a copy is made.

One advantage of structs in connection with functions is that a function can only return a single value; but you can return (for example) two ints by using a struct of two ints and returning an item of that struct type.


Full syntax

It looks like we have two totally different struct declaration syntaxes above, but actually they're both special cases of the general form.

A struct declaration in C can declare a struct tag (type), or items of that struct type, or both.

The syntax begins with the keyword "struct". Then there is an optional tag name, an optional struct member list (in braces), an optional list of variable names being declared, and then a semicolon.

If there is a struct member list in braces, then this declaration is creating that struct type. In this case, if there is a tag then it creates that struct tag name and associates it with this member list.

If there is a struct tag but no struct member list in braces, then this declaration is declaring variables in the list to be of that struct type, but not saying what the struct type is. In most cases the struct tag must have previously been declared with the actual struct member list in braces. (We'll see an exception to this in assignment two.)

Then, the variable list, if present, causes variables to be declared in the normal C way. Other modifiers such as storage classes and declaration type modifiers can be applied. For example, you can say "extern struct something x;" to declare that "x" is a global variable of type "struct something"; or you can say "struct something a[100];" to declare 'a' to be an array of 100 struct somethings.

Examples:

1. Create type "struct point", as above.

struct point {
    int x, y;
};

2. Simultaneously create type "struct point" and declare variable "a" to be of this type.

struct point {
    int x, y;
} a;

3. Declare variable "a" to be of type "struct point", when that type was previously created (e.g. by #1 above).

struct point a;

4. Declare variable "b" to be an array of 100 structs each containing an int and a double.

struct {
    int x;
    double y;
} b[100];

5. Assign the second member of item 38 of the array defined in #4 to have the value 123.456.

b[38].y = 123.456;


[
list of topics covered, evening section]
[course notes available (evening section)]
[main course page]