# Structures, enumerations and types (9)

Antonin Hérault
·Aug 24, 2022·

Subscribe to my newsletter and never miss my upcoming articles

• Structures
• Type definition
• Enumerations
• Methods with structures
• Exercises
• Solutions

You may already asked how to create an array with different data types. Like a tuple. This is not possible, but we can create structures of data !

## Structures

``````struct <identifier> {
<type> <identifier>; // attribute 1
<type> <identifier>; // attribute 2
...
};
``````

This is an example creating a structure object :

``````#include <assert.h>

struct s_user {
char* name;
int age;
};

int main(void) {
struct s_user user1 = { "John", 34 };
assert(user1.age == 34);

return 0;
}
``````

As you can see, we can access to the object's elements with the following syntax :

``````<object identifier>.<attribute identifier>
``````

## Type definition

``````typedef struct <struct identifier> <type identifier>;
``````

We usually define a type for structures we create.

``````typedef struct s_user {
char* name;
int age;
} User;
``````
``````struct s_user {
char* name;
int age;
};
typedef struct s_user User;
``````

It's also possible to make an anonymous structure while using the first method :

``````typedef struct {
char* name;
int age;
} User;
``````

## Enumerations

Imagine that we want to store the user's job, we could store it into a string. But a better way to do it exists : enumerations.

``````typedef enum e_job {
Builder,
Dentist,
Engineer,
Fireman,
Lawyer,
Teacher,
Waiter
} Job;
``````

We can add a `Job` attribute to our `User` structure :

``````typedef struct s_user {
char* name;
int age;
Job job;
} User;
``````

In some language, an enumeration element can be retrieved by the `Enum::Element` syntax. But in C, you directly have an access to the elements, without post fixing with the enumeration identifier.

Using enumerations is a smarter way to define something than a string object, and it takes less memory space.

``````int main(void) {
User user1 = { "John", 34, Builder };
printf("sizeof(User user1) == %li\n", sizeof(user1));
printf("sizeof(Job Builder) == %li\n", sizeof(Builder));
printf("sizeof(char* \"builder\") == %li\n", sizeof("builder"));

return 0;
}
``````
``````sizeof(User user1) == 16
sizeof(Job Builder) == 4
sizeof(char* "builder") == 8
``````

With enumerations, it's possible to set a value for an element in the declaration :

``````typedef enum {
Working = 1,
Failed = 0,
Freezed = -1
} State;
``````

## Methods with structures

The C language does not embed classes, so there are no methods. But, we can recreate this principle thanks to the pointers

``````User new_user(char* name, int age, Job job) {
User temp = { name, age, job };
return temp;
}

void print_user(User user) {
printf("User(%s, %i, %s)\n", user.name, user.age, job_to_string(user.job));
}

void change_user_job(User* user, Job job) {
user->job = job;
}

void free_user(User* user) {
user->name = (char*) NULL;
user->age = -1;
user->job = Null;
user = (User*) NULL;
}
``````

What does `user-><attribute>` means ? Why we sometimes use it instead of `user.<attribute>` ?

When we manipulate a pointer of a structure object, we cannot directly access to the attributes. We have to get the pointer's pointing value (as seen in this article) :

``````int n = 5;
int* ptr_n = &n;
assert(*ptr_n == 5); // pointed value retrieved
``````

So, we are supposed to do that :

``````(*user).job
``````

We have to embrace `user` because `*user.job` cannot be done because it would mean that we want to retrieve the pointing value of `job`.

But, it's a boring syntax, so the C language allows to use the `->` symbol instead, to make things easier.

``````(*user).job = user->job
``````

## Exercises

1. Write the "`Job` element converter to string" function using a switch statement
2. Create an enumeration with the 7 days of the week, every element has to be assigned by its day week number. In addition to that, create the following function :
``````int is_weekend(DayWeek day_week);
``````

## Solutions

1. Write the "`Job` element converter to string" function using a switch statement

``````char* job_to_string(Job job) {
switch (job) {
case Builder:
return "Builder";
case Dentist:
return "Dentist";
case Engineer:
return "Engineer";
case Fireman:
return "Fireman";
case Lawyer:
return "Lawyer";
case Teacher:
return "Teacher";
case Waiter:
return "Waiter";
case Null:
return "(null)";
}
}
``````
2. Create an enumeration with the 7 days of the week, every element has to be assigned by its day of the week number. In addition of that, create the following function :

``````int is_weekend(DayWeek day_week);
``````
``````#include <assert.h>

typedef enum {
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6,
Sunday = 7
} DayWeek;

int is_weekend(DayWeek day_week) {
// A weekday, not a day of the weekend
if (day_week != 6 && day_week != 7) {
return 0;
}
return 1;
}

int main() {
assert(Monday == 1);
assert(Sunday == 7);
assert(is_weekend(Wednesday) != 1);
assert(is_weekend(Saturday) == 1);

return 0;
}
``````