assign3: Structs Overview

Written by Nick Troccoli

Structs are used on this assignment to bundle variables together. A struct is a way to define a new variable type that is a group of other variables.

// declaring a struct type
struct date {
    int month;
    int day;        // members of each date structure
};
…

// construct structure instances
struct date today;                 
today.month = 1;
today.day = 28;

// shorter initializer syntax
struct date new_years_eve = {12, 31};

We commonly wrap the struct definition in a typedef to avoid having to include the word "struct" every time we make a new variable of that type:

typedef struct date {       
    int month;
    int day;        
} date;
…

// now we can just say 'date', not 'struct date'
date today;
today.month = 1;
today.day = 28;

date new_years_eve = {12, 31};   

If you pass a struct as a parameter, like for other parameters, C passes a copy of the entire struct.

void advance_day(date d) {
    d.day++;
}

int main(int argc, char *argv[]) {
    date my_date = {1, 28};
    advance_day(my_date);
    printf("%d", my_date.day);  // 28
    return 0;
}

If we want to modify a specific instance of a struct, we can use a pointer to it:

void advance_day(date *d) {
    (*d).day++;
}

int main(int argc, char *argv[]) {
    date my_date = {1, 28};
    advance_day(&my_date);
    printf("%d", my_date.day);  // 29
    return 0;
}

Dereferencing a struct and getting a single field within it is a common operation - the arrow operator lets you access the field of a struct pointed to by a pointer in a single step:

void advance_day(date *d) {
    d->day++;       // equivalent to (*d).day++;
}

C allows you to return structs from functions as well. It returns whatever is contained within the struct.

date create_new_years_date() {
    date d = {1, 1};
     return d;      // or return (date){1, 1};
}

int main(int argc, char *argv[]) {
    date my_date = create_new_years_date();
    printf("%d", my_date.day);  // 1
    return 0;
}

sizeof gives you the entire size of a struct, which is the sum of the sizes of all its contents.

typedef struct date {
        int month;
        int day;       
    } date;

int main(int argc, char *argv[]) {
    int size = sizeof(date);    // 8    
        return 0;
}

Lastly, you can create arrays of structs just like any other variable type.

typedef struct my_struct {
    int x;
    char c;
} my_struct;

…

my_struct array_of_structs[5];

To initialize an entry of the array, you must use this special syntax to confirm the type to C.

typedef struct my_struct {
    int x;
    char c;
} my_struct;

…

my_struct array_of_structs[5];
array_of_structs[0] = (my_struct){0, 'A'};

You can also set each field individually.

typedef struct my_struct {
    int x;
    char c;
} my_struct;

…
my_struct array_of_structs[5];
array_of_structs[0].x = 2;
array_of_structs[0].c = 'A';