Road to C Programmer #4 - Structs & Enums

Last Edited: 7/25/2024

The blog post is about structs and enums in C.

C Structs & Enums

Structs

A struct is like a class in object-oriented programming without methods. It can store variables of different types together under one name in a block of memory (it's similar to data in Haskell). A struct can be defined as follows:

// Defining new struct
struct User {
    char name[15];
    int age;
    char password[15];
};
 
int main () {
    // Declaration
    struct User user1;
 
    // Initialization
    strcpy(user1.name, "TK");
    user1.age = 20;
    strcpy(user1.password, "random123");
    
    // Declaration + Initialization
    struct User user2 = {"KT", 20, "Random123"};
    struct User user3 = { .name = "KT", .age = 20, .password = "Random123"};
 
    return 0;
}

You can treat it just like a new datatype with properties. Hence, you can make an array of structs as well, like below.

int main () {
    
    // Declaration + Initialization
    struct User user1 = {"TK", 20, "Random123"};
    struct User user2 = {"KT", 20, "Random123"};
    struct User user3 = {"TKBlog", 20, "Random123"};
 
    // Array of Struct
    struct User users[] = {user1, user2, user3};
 
    // Iterating over array of struct with sizeof
    for (int i = 0; i < sizeof(users)/sizeof(users[0]); i++) {
        printf("%-12s", users[i].name);
        printf("%d", users[i].age);
    }
 
    return 0;
}

However, typing struct User every time is tedious. We can use typedef to simplify the syntax.

// Using typedef to define struct "User"
typedef struct {
    char name[15];
    int age;
    char password[15];
} User;
 
int main () {
    // Now, we don't need `struct`
    User user1 = {"TK", 20, "Random123"};
    User user2 = {"KT", 20, "Random123"};
    User user3 = {"TKBlog", 20, "Random123"};
 
    return 0;
}

The typedef is a useful way of giving a new name to an existing datatype (just like type in Haskell). It can also be used for other existing datatypes.

typedef char user[15];
 
int main () {
    user user1 = "TK";
    return 0;
}

Enums

Another concept that can simplify the code is enums, which can create a set of constants with associated integers. Let's say you have conditions depending on the days of the week. You can do it like this.

int main () {
 
    // Day : Number
    // Sun : 0
    // Mon : 1
    //     :
    // Sat : 7
 
    int today = 0;
 
    if (today == 0 || today == 6) {
        printf("Weekends!");
    } else {
        printf("Weekday");
    }
 
    return 0;
}

You can assign an integer to each day of the week like the above and have a comment at the top indicating which integer corresponds to which day. However, this is not very readable. This is where enums come in.

enum Day{Sun, Mon, Tue, Wed, Thu, Fri, Sat};
// ^ automatically assign value from 0 to 6 to each of the constants
 
int main () {
 
    enum Day today = Sun; // treated like an integer Sun = 0
 
    if (today == Sun || today == Sat) {
        printf("Weekends!");
    } else {
        printf("Weekday");
    }
 
    // You can even compare against an int because they are inherently the same
    if (today == 0) {
        printf("Today is Sunday. ");
    }
 
    return 0;
}

The above makes the code so much more readable while achieving the same thing. If you want the day to start from 1, then we can do so as follows.

enum Day{Sun=1, Mon=2, Tue=3, Wed=4, Thu=5, Fri=6, Sat=7};

Exercises

From this article, there will be an exercise section where you can test your understanding of the material introduced in the article. I highly recommend solving these questions by yourself after reading the main part of the article. You can click on each question to see its answer.

Resources