C-Structs

Structs

We need some more powerful compounding data structures besides arrays

Declaring & using struct variables

There are two steps needed for declaring them. First we define a new struct type:

struct sname {
  // field declarations
};

For example:

struct person {
 char * first, * last;
 int age;
};

Next, declare variables of the struct type

struct person p1, p2; // notice how "struct" precedes name

We can both define a struct and declare variables p1 and p2 at the same time. This is not used too often:

struct person {
  char * first, *last;
  int age;
} p1, p2;

Once declared, the dot operator is used to access struct fields: p1.age = p1.age + 1.

Initializing structs

Can initialize struct variables during declaration:

Passing structs to functions

Pointers to structs

Pointers to structs are commonly used. A very common expression is (*sptr).part as in this example.

struct person *ppp = malloc(sizeof(struct person));
(*ppp).age = 33;

In fact its so common, it has a shortcut:

ppp->age = 33 ; //same as (*ppp).age = 33;

NOTE: operators () [] . -> have the highest precedence (full C operator precedence reference)
*ppp.age = 33 is a compile error, need parens (*ppp).age = 33;

Composing structs with other types

Type abbreviations via typedef

We use typedef to declare type abbreviations for easier typing / reading:

typedef void * blackhole; // new <em>type</em> blackhole defined
blackhole myblackhole; // declares myblackhole as a blackhole, i.e. as a void *

This is especially common with struct definitions:

typedef struct {      // note the struct itself is anonymous -- no name given here
  int n1, n2, n3;
} SSN;                // SSN is the type abbreviation
SSN myssn;            // no "struct" needed when declaring, "struct" is part of SSN

Sizes of structs

Enum types

We can also define a data type to represent a small set of discrete values. Suppose you had a game with playing cards, hearts/clubs/spades/diamonds. Don’t just use the strings "Hearts" etc or 1/2/3/4 in the code for these different suits. Instead you can #define them

#define HEARTS 1
#define CLUBS 2
#define SPADES 3
#define DIAMONDS 4

Enum version of this is more compact and also defines a data type called suit that can be used to declare variables, parameters, etc.

enum suit {HEARTS=1,CLUBS,SPADES,DIAMONDS}

Same numerical abbreviation but makes a new type suit for the values (which is really an integer under the covers). The =1 makes the encoded numbers start at 1 not 0, which is the default. Each subsequent label gets the next integer value.