-->

C Programming Day 10: Structures & Unions in C | Complete Guide

C Programming Day 10

C Programming Day 10 Structures and Unions in C tutorial


    Introduction

    Welcome to Day 10 of the C Programming Full Course.

    In the previous lesson, you learned about Pointers in C, including memory addresses, dereferencing, pointer arithmetic, pointers with arrays, and pointers with functions.

    Today, we are going to learn two important C programming concepts:

    Structures and unions allow programmers to organize related data into a single user-defined type.

    For example, imagine you want to store information about a student:

    Student Name
    Student ID
    Age
    Marks
    Grade

    These values can have different data types.

    Instead of keeping them as unrelated variables:

    char name[50];
    int id;
    int age;
    float marks;
    char grade;

    we can group them together using a structure.

    struct Student
    {
        char name[50];
        int id;
        int age;
        float marks;
        char grade;
    };

    This makes complex programs much easier to organize.


    What is a Structure in C?

    A structure is a user-defined data type that allows you to combine variables of different data types under one name.

    For example:

    struct Student
    {
        int id;
        char name[50];
        float marks;
    };

    Here, Student contains three members:

    • id
    • name
    • marks

    Each member can have a different data type.


    Why Use Structures?

    Structures are useful when several pieces of information belong to the same entity.

    For example, an employee may have:

    Employee ID
    Employee Name
    Salary
    Department

    A structure allows us to represent them together:

    struct Employee
    {
        int id;
        char name[50];
        float salary;
        char department[50];
    };

    This approach makes programs more organized and easier to maintain.


    Structure Syntax

    The general syntax is:

    struct StructureName
    {
        data_type member1;
        data_type member2;
        data_type member3;
    };

    Example:

    struct Student
    {
        int id;
        char name[50];
        float marks;
    };

    Notice the semicolon after the closing brace:

    };

    This is required.


    Declaring Structure Variables

    After defining a structure, you can create variables of that structure type.

    struct Student
    {
        int id;
        char name[50];
        float marks;
    };
    
    int main()
    {
        struct Student student1;
    
        return 0;
    }

    Here:

    struct Student

    is the structure type, while:

    student1

    is a structure variable.


    Accessing Structure Members

    The dot operator . is used to access members of a structure variable.

    Example:

    #include <stdio.h>
    
    struct Student
    {
        int id;
        float marks;
    };
    
    int main()
    {
        struct Student student1;
    
        student1.id = 101;
        student1.marks = 85.5f;
    
        printf("ID = %d\n", student1.id);
        printf("Marks = %.2f\n", student1.marks);
    
        return 0;
    }

    Output:

    ID = 101
    Marks = 85.50

    Structure with a String Member

    A structure can contain character arrays.

    #include <stdio.h>
    #include <string.h>
    
    struct Student
    {
        int id;
        char name[50];
        float marks;
    };
    
    int main()
    {
        struct Student student1;
    
        student1.id = 101;
        strcpy(student1.name, "Jitu");
        student1.marks = 90.5f;
    
        printf("ID: %d\n", student1.id);
        printf("Name: %s\n", student1.name);
        printf("Marks: %.2f\n", student1.marks);
    
        return 0;
    }

    Output:

    ID: 101
    Name: Jitu
    Marks: 90.50

    Because name is an array, assigning a string with = after declaration is not valid. Functions such as strcpy() can be used, with appropriate care for buffer size.


    Initializing a Structure

    A structure can be initialized when it is declared.

    #include <stdio.h>
    
    struct Student
    {
        int id;
        char name[50];
        float marks;
    };
    
    int main()
    {
        struct Student student1 = {101, "Jitu", 88.5f};
    
        printf("ID = %d\n", student1.id);
        printf("Name = %s\n", student1.name);
        printf("Marks = %.2f\n", student1.marks);
    
        return 0;
    }

    Output:

    ID = 101
    Name = Jitu
    Marks = 88.50

    Designated Initializers

    C also supports designated initializers.

    Example:

    struct Student student1 = {
        .id = 101,
        .name = "Jitu",
        .marks = 88.5f
    };

    This can make initialization clearer, especially when structures contain many members.

    Taking Input into a Structure

    Example:

    #include <stdio.h>
    
    struct Student
    {
        int id;
        char name[50];
        float marks;
    };
    
    int main()
    {
        struct Student student;
    
        printf("Enter student ID: ");
        scanf("%d", &student.id);
    
        printf("Enter student name: ");
        scanf("%49s", student.name);
    
        printf("Enter marks: ");
        scanf("%f", &student.marks);
    
        printf("\nStudent Information\n");
        printf("ID: %d\n", student.id);
        printf("Name: %s\n", student.name);
        printf("Marks: %.2f\n", student.marks);
    
        return 0;
    }

    Using a width such as %49s helps prevent writing more characters than the array can hold for this particular input method.

    For names containing spaces, fgets() is generally more appropriate.


    Array of Structures

    One of the most useful features of structures is creating an array of structures.

    Suppose you want to store information about five students.

    Instead of creating:

    struct Student student1;
    struct Student student2;
    struct Student student3;
    struct Student student4;
    struct Student student5;

    you can create:

    struct Student students[5];

    Now each element is a complete struct Student.

    Example: Array of Students

    #include <stdio.h>
    
    struct Student
    {
        int id;
        char name[50];
        float marks;
    };
    
    int main()
    {
        struct Student students[3] =
        {
            {101, "Jitu", 85.5f},
            {102, "Rahim", 90.0f},
            {103, "Karim", 78.5f}
        };
    
        int i;
    
        for(i = 0; i < 3; i++)
        {
            printf("ID: %d\n", students[i].id);
            printf("Name: %s\n", students[i].name);
            printf("Marks: %.2f\n\n", students[i].marks);
        }
    
        return 0;
    }

    Output:

    ID: 101
    Name: Jitu
    Marks: 85.50
    
    ID: 102
    Name: Rahim
    Marks: 90.00
    
    ID: 103
    Name: Karim
    Marks: 78.50

    Input for an Array of Structures

    #include <stdio.h>
    
    struct Student
    {
        int id;
        char name[50];
        float marks;
    };
    
    int main()
    {
        struct Student students[3];
        int i;
    
        for(i = 0; i < 3; i++)
        {
            printf("\nEnter student %d information\n", i + 1);
    
            printf("ID: ");
            scanf("%d", &students[i].id);
    
            printf("Name: ");
            scanf("%49s", students[i].name);
    
            printf("Marks: ");
            scanf("%f", &students[i].marks);
        }
    
        printf("\n--- Student Records ---\n");
    
        for(i = 0; i < 3; i++)
        {
            printf("\nID: %d", students[i].id);
            printf("\nName: %s", students[i].name);
            printf("\nMarks: %.2f\n", students[i].marks);
        }
    
        return 0;
    }


    Nested Structures

    A structure can contain another structure as a member.

    This is called a nested structure.

    For example, a student may have an address:

    Student
     ├── ID
     ├── Name
     └── Address
          ├── City
          ├── Country
          └── ZIP Code

    We can represent this using two structures.

    struct Address
    {
        char city[50];
        char country[50];
        int zip;
    };
    
    struct Student
    {
        int id;
        char name[50];
        struct Address address;
    };

    Example of Nested Structure

    #include <stdio.h>
    
    struct Address
    {
        char city[50];
        char country[50];
        int zip;
    };
    
    struct Student
    {
        int id;
        char name[50];
        struct Address address;
    };
    
    int main()
    {
        struct Student student =
        {
            101,
            "Jitu",
            {"Dhaka", "Bangladesh", 1200}
        };
    
        printf("ID: %d\n", student.id);
        printf("Name: %s\n", student.name);
        printf("City: %s\n", student.address.city);
        printf("Country: %s\n", student.address.country);
        printf("ZIP: %d\n", student.address.zip);
    
        return 0;
    }

    Output:

    ID: 101
    Name: Jitu
    City: Dhaka
    Country: Bangladesh
    ZIP: 1200


    Structures with Functions

    Structures can be passed to functions.

    Example:

    #include <stdio.h>
    
    struct Student
    {
        int id;
        float marks;
    };
    
    void displayStudent(struct Student student)
    {
        printf("ID: %d\n", student.id);
        printf("Marks: %.2f\n", student.marks);
    }
    
    int main()
    {
        struct Student student = {101, 85.5f};
    
        displayStudent(student);
    
        return 0;
    }

    The structure is passed by value, so the function receives a copy.


    Passing a Structure Using a Pointer

    For larger structures, you may want to pass a pointer to avoid copying the entire structure.

    #include <stdio.h>
    
    struct Student
    {
        int id;
        float marks;
    };
    
    void displayStudent(const struct Student *student)
    {
        printf("ID: %d\n", student->id);
        printf("Marks: %.2f\n", student->marks);
    }
    
    int main()
    {
        struct Student student = {101, 85.5f};
    
        displayStudent(&student);
    
        return 0;
    }

    The const indicates that this function should not modify the structure through the pointer.

    Structure Pointer

    A pointer can point to a structure.

    struct Student student;
    
    struct Student *ptr;
    
    ptr = &student;

    The pointer now stores the address of student.


    Arrow Operator ->

    When accessing structure members through a pointer, use the arrow operator ->.

    Example:

    ptr->id

    This is equivalent to:

    (*ptr).id

    Example:

    #include <stdio.h>
    
    struct Student
    {
        int id;
        float marks;
    };
    
    int main()
    {
        struct Student student = {101, 90.5f};
    
        struct Student *ptr = &student;
    
        printf("ID = %d\n", ptr->id);
        printf("Marks = %.2f\n", ptr->marks);
    
        return 0;
    }

    Output:

    ID = 101
    Marks = 90.50

    Structure vs Pointer to Structure

    With a normal structure variable:

    student.id

    With a structure pointer:

    ptr->id

    Remember:

    Structure variable → .
    Structure pointer  → ->


    Structure Containing an Array

    A structure can contain arrays.

    struct Student
    {
        int id;
        char name[50];
        int marks[5];
    };

    This can be useful for storing marks for multiple subjects.

    Example:

    #include <stdio.h>
    
    struct Student
    {
        int id;
        char name[50];
        int marks[5];
    };
    
    int main()
    {
        struct Student student =
        {
            101,
            "Jitu",
            {80, 85, 90, 75, 88}
        };
    
        int i;
    
        printf("Student: %s\n", student.name);
    
        for(i = 0; i < 5; i++)
        {
            printf("Subject %d: %d\n", i + 1, student.marks[i]);
        }
    
        return 0;
    }


    Practical Program 1: Student Management

    Let's combine structures, arrays, loops, and functions.

    #include <stdio.h>
    
    struct Student
    {
        int id;
        char name[50];
        float marks;
    };
    
    void displayStudent(struct Student student)
    {
        printf("ID: %d\n", student.id);
        printf("Name: %s\n", student.name);
        printf("Marks: %.2f\n", student.marks);
    }
    
    int main()
    {
        struct Student students[3];
        int i;
    
        for(i = 0; i < 3; i++)
        {
            printf("\nEnter Student %d\n", i + 1);
    
            printf("ID: ");
            scanf("%d", &students[i].id);
    
            printf("Name: ");
            scanf("%49s", students[i].name);
    
            printf("Marks: ");
            scanf("%f", &students[i].marks);
        }
    
        printf("\n===== Student Records =====\n");
    
        for(i = 0; i < 3; i++)
        {
            displayStudent(students[i]);
            printf("--------------------\n");
        }
    
        return 0;
    }

    This program demonstrates how structures can be used to build a basic record-management system.


    Practical Program 2: Employee Management

    #include <stdio.h>
    
    struct Employee
    {
        int id;
        char name[50];
        float salary;
    };
    
    int main()
    {
        struct Employee employees[3];
        int i;
    
        for(i = 0; i < 3; i++)
        {
            printf("\nEnter Employee %d\n", i + 1);
    
            printf("ID: ");
            scanf("%d", &employees[i].id);
    
            printf("Name: ");
            scanf("%49s", employees[i].name);
    
            printf("Salary: ");
            scanf("%f", &employees[i].salary);
        }
    
        printf("\n===== Employee Information =====\n");
    
        for(i = 0; i < 3; i++)
        {
            printf("\nID: %d\n", employees[i].id);
            printf("Name: %s\n", employees[i].name);
            printf("Salary: %.2f\n", employees[i].salary);
        }
    
        return 0;
    }


    Practical Program 3: Product Management

    Structures are also useful for representing products.

    #include <stdio.h>
    
    struct Product
    {
        int id;
        char name[50];
        float price;
        int quantity;
    };
    
    int main()
    {
        struct Product product =
        {
            1001,
            "Laptop",
            75000.0f,
            5
        };
    
        float inventoryValue;
    
        inventoryValue = product.price * product.quantity;
    
        printf("Product ID: %d\n", product.id);
        printf("Product: %s\n", product.name);
        printf("Price: %.2f\n", product.price);
        printf("Quantity: %d\n", product.quantity);
        printf("Inventory Value: %.2f\n", inventoryValue);
    
        return 0;
    }


    Practical Program 4: Find the Highest Marks

    #include <stdio.h>
    
    struct Student
    {
        int id;
        char name[50];
        float marks;
    };
    
    int main()
    {
        struct Student students[5] =
        {
            {101, "Jitu", 85.0f},
            {102, "Rahim", 92.0f},
            {103, "Karim", 78.0f},
            {104, "Hasan", 95.0f},
            {105, "Rafi", 88.0f}
        };
    
        int i;
        int highest = 0;
    
        for(i = 1; i < 5; i++)
        {
            if(students[i].marks > students[highest].marks)
            {
                highest = i;
            }
        }
    
        printf("Highest Marks Student\n");
        printf("ID: %d\n", students[highest].id);
        printf("Name: %s\n", students[highest].name);
        printf("Marks: %.2f\n", students[highest].marks);
    
        return 0;
    }

    Output:

    Highest Marks Student
    ID: 104
    Name: Hasan
    Marks: 95.00


    What is a Union in C?

    A union is another user-defined data type.

    Like a structure, a union can contain multiple members with different data types.

    However, there is a major difference:

    Structure members have separate storage, while union members share the same storage.

    Example:

    union Data
    {
        int number;
        float price;
        char letter;
    };

    All three members share the same memory area.


    Union Syntax

    The general syntax is:

    union UnionName
    {
        data_type member1;
        data_type member2;
        data_type member3;
    };

    Example:

    union Data
    {
        int number;
        float price;
        char letter;
    };

    Creating a Union Variable

    union Data data;

    You can then assign a member:

    data.number = 100;

    or:

    data.price = 25.5f;

    But remember that the members share storage.


    Accessing Union Members

    Example:

    #include <stdio.h>
    
    union Data
    {
        int number;
        float price;
        char letter;
    };
    
    int main()
    {
        union Data data;
    
        data.number = 100;
    
        printf("Number = %d\n", data.number);
    
        data.price = 25.5f;
    
        printf("Price = %.2f\n", data.price);
    
        return 0;
    }

    When price is assigned, it uses the same storage that was previously used for number.

    Therefore, you should generally treat only the currently stored member as the active value.


    Structure vs Union

    This is one of the most important differences in this lesson.

    FeatureStructureUnion
    Keywordstructunion
    StorageMembers have separate storageMembers share storage
    Members usable simultaneouslyYesGenerally one active member at a time
    SizeUsually enough for all members plus alignment/paddingAt least enough for the largest member, subject to alignment
    Main purposeGroup related dataStore alternative representations efficiently
    Data preservationValues of members coexistWriting one member can affect the representation of others

    Structure Memory Example

    Consider:

    struct Data
    {
        int number;
        float price;
        char letter;
    };

    Conceptually, memory contains storage for all members:

    ┌──────────────┐
    │ number       │
    ├──────────────┤
    │ price        │
    ├──────────────┤
    │ letter       │
    └──────────────┘

    Padding may also be inserted by the compiler for alignment.


    Union Memory Example

    For:

    union Data
    {
        int number;
        float price;
        char letter;
    };

    the members overlap:

    ┌─────────────────────┐
    │ Shared Storage      │
    │ number / price /    │
    │ letter               │
    └─────────────────────┘

    The size is related to the largest member and required alignment, rather than the sum of all member sizes.

    Checking Structure and Union Size

    You can use sizeof().

    #include <stdio.h>
    
    struct Data
    {
        int number;
        float price;
        char letter;
    };
    
    union DataUnion
    {
        int number;
        float price;
        char letter;
    };
    
    int main()
    {
        printf("Structure size: %zu bytes\n", sizeof(struct Data));
        printf("Union size: %zu bytes\n", sizeof(union DataUnion));
    
        return 0;
    }

    The exact sizes depend on the platform, compiler, data types, alignment, and padding.


    Practical Union Example

    A union can be useful when a record needs to hold one of several alternative data types.

    For example:

    #include <stdio.h>
    
    union Value
    {
        int integerValue;
        float floatValue;
        char textValue[20];
    };
    
    int main()
    {
        union Value value;
    
        value.integerValue = 100;
    
        printf("Integer: %d\n", value.integerValue);
    
        value.floatValue = 25.5f;
    
        printf("Float: %.2f\n", value.floatValue);
    
        return 0;
    }

    The same memory is reused for different representations.


    When Should You Use a Structure?

    Use a structure when you need to store multiple related values at the same time.

    Examples:

    Student
    Employee
    Product
    Book
    Customer
    Bank Account
    Vehicle

    For example:

    struct Product
    {
        int id;
        char name[50];
        float price;
    };

    All three pieces of information are needed simultaneously.


    When Should You Use a Union?

    Use a union when different members represent alternative ways of using the same storage.

    Potential applications include:

    • Memory-constrained programs
    • Embedded systems
    • Low-level programming
    • Tagged or variant-style data representations
    • Protocol/data representation tasks

    When designing a union-based representation, the program should keep track of which member is currently valid. A common technique is to pair the union with an enum tag.


    Structure with Union

    Structures and unions can also be combined.

    Example:

    #include <stdio.h>
    
    enum ValueType
    {
        INTEGER,
        FLOAT_VALUE
    };
    
    union Value
    {
        int integerValue;
        float floatValue;
    };
    
    struct Data
    {
        enum ValueType type;
        union Value value;
    };
    
    int main()
    {
        struct Data data;
    
        data.type = INTEGER;
        data.value.integerValue = 100;
    
        if(data.type == INTEGER)
        {
            printf("Integer = %d\n", data.value.integerValue);
        }
    
        return 0;
    }

    This is a common design pattern for representing data that can have different forms.


    Common Mistakes with Structures

    1. Forgetting the Semicolon

    Incorrect:

    struct Student
    {
        int id;
    }

    Correct:

    struct Student
    {
        int id;
    };

    2. Using . with a Structure Pointer

    Incorrect:

    ptr.id

    Correct:

    ptr->id

    3. Using -> with a Normal Structure Variable

    If:

    struct Student student;

    use:

    student.id

    not:

    student->id

    4. Forgetting the Address Operator with scanf()

    For an integer member:

    scanf("%d", &student.id);

    For a character array:

    scanf("%49s", student.name);

    The array name already represents an address in this context, so do not write &student.name for %s.


    Common Mistakes with Unions

    Mistake 1: Assuming All Members Store Independent Values

    They don't. Union members share storage.

    Mistake 2: Treating Every Member as Simultaneously Valid

    Writing one member changes the stored representation.

    Mistake 3: Ignoring Which Union Member Is Active

    In designs where multiple possible types exist, maintain a tag describing which member should be interpreted.


    Structures vs Arrays

    Arrays store multiple values of the same type.

    Example:

    int marks[5];

    Structures can store related values of different types.

    Example:

    struct Student
    {
        int id;
        char name[50];
        float marks;
    };

    Therefore:

    Array → Collection of similar data
    Structure → Collection of related data, potentially of different types

    Structures can also contain arrays, making them very powerful for representing real-world records.


    Structures and Pointers

    The previous lesson introduced pointers.

    Now we can combine pointers with structures:

    struct Student
    {
        int id;
        float marks;
    };
    
    struct Student student = {101, 90.0f};
    
    struct Student *ptr = &student;

    Access:

    ptr->id

    and:

    ptr->marks

    This connection between pointers and structures becomes particularly important when you later learn about dynamic memory allocation and linked lists.


    Best Practices for Structures and Unions

    Use Meaningful Structure Names

    Prefer:

    struct Student

    over:

    struct S

    Keep Related Data Together

    If several values describe the same entity, consider whether a structure is appropriate.

    Use Functions to Organize Operations

    For example:

    addStudent()
    displayStudent()
    searchStudent()
    updateStudent()

    Use Pointers for Large Structures When Appropriate

    Passing a pointer can avoid copying the entire structure.

    Use const for Read-Only Structure Pointers

    Example:

    void display(const struct Student *student);

    Use Unions Carefully

    Always know which union member currently contains the intended representation.


    Interview Questions on Structures and Unions

    1. What is a structure in C?

    A structure is a user-defined type that groups related objects, potentially of different types, under one name.

    2. What is a union?

    A union is a user-defined type whose members share overlapping storage.

    3. What is the difference between . and ->?

    . accesses a member through a structure or union object.

    -> accesses a member through a pointer to a structure or union.

    4. Can a structure contain another structure?

    Yes. This is called a nested structure.

    5. Can a structure contain an array?

    Yes.

    6. Can an array contain structures?

    Yes. This is called an array of structures.

    7. What is the main difference between a structure and a union?

    Structure members have separate storage, while union members share the same storage.

    8. Can a structure be passed to a function?

    Yes. It can be passed by value or through a pointer.

    9. Why use a pointer to a structure?

    A pointer can avoid copying a large structure and allows a function to modify the original structure when appropriate.

    10. What does ptr->member mean?

    It accesses member through the structure or union object pointed to by ptr.


    Practice Problems

    Beginner

    • Create a struct Student containing ID, name, and marks.
    • Initialize and display a student.
    • Create a struct Employee.
    • Store product information using a structure.
    • Create a structure for a book.
    • Create a structure for a bank account.

    Intermediate

    • Create an array of 5 students.
    • Find the student with the highest marks.
    • Find the student with the lowest marks.
    • Calculate the average marks of students.
    • Search for a student by ID.
    • Update a student's marks.
    • Create a nested Address structure.
    • Pass a structure to a function.
    • Pass a structure to a function using a pointer.

    Advanced

    • Build a student management system using structures.
    • Build an employee management system.
    • Build a product inventory system.
    • Create a structure containing an array of subject marks.
    • Build a menu-driven record management program.
    • Create a tagged union example.
    • Explore how structures and unions differ in size using sizeof().


    Day 10 Summary

    In C Programming Day 10, you learned how to use Structures and Unions in C.

    You learned:

    • What structures are
    • Why structures are useful
    • Structure declaration
    • Structure variables
    • Structure members
    • Member access using .
    • Structure initialization
    • Designated initializers
    • Input and output with structures
    • Arrays of structures
    • Nested structures
    • Structures with arrays
    • Structures with functions
    • Structure pointers
    • Arrow operator ->
    • What unions are
    • Union declaration
    • Union members
    • Structure vs union
    • Union memory sharing
    • Tagged union concepts
    • Practical real-world programs
    • Common mistakes
    • Best practices

    The key concepts to remember are:

    Structure Variable
            ↓
        object.member
    
    Structure Pointer
            ↓
        pointer->member
    
    Union
            ↓
    Members share storage

    Structures are especially important for representing real-world entities such as students, employees, products, customers, books, and accounts.

    Unions become useful when multiple alternative data representations need to share the same memory.


    Conclusion

    Congratulations! 🎉 You have completed C Programming Day 10 — Structures & Unions in C.

    You have now moved beyond basic variables and arrays and learned how to create your own custom data types for organizing complex information.

    Structures allow you to group related information into a single object, while unions allow multiple members to share the same memory storage. You also learned how structures work with arrays, nested structures, functions, pointers, and practical record-management programs.

    The connection between today's lesson and the previous lessons is especially important:

    Variables
       ↓
    Arrays
       ↓
    Functions
       ↓
    Pointers
       ↓
    Structures & Unions

    These concepts form an important foundation for more advanced C programming.

    In the next lesson, we'll move into C File Handling, where you'll learn how to create, open, read, write, append, and manage files using C.

    Keep practicing, keep coding, and continue your C Programming journey!



    Frequently Asked Questions (FAQ)

    What is the main purpose of a structure in C?
    A structure groups related data, potentially of different types, into a single user-defined type
    What is the main purpose of a union?
    A union allows multiple members to share the same storage, which can be useful when only one of several alternative representations is needed at a time.
    Which operator accesses a structure member?
    Use the dot operator: student.id
    Which operator accesses a member through a structure pointer?
    Use: studentPtr->id
    Can structures contain other structures?
    Yes. Nested structures are commonly used to model hierarchical data.
    Can we create an array of structures?
    Yes: struct Student students[10];
    Do union members have separate memory?
    No. Union members share overlapping storage.

    0/Post a Comment/Comments

    Thank You For Visit My Website.
    I Will Contact As Soon As Possible.