Structures in C – Struct with Examples (Student, Product, Device Data)

Structures in C – Struct with Examples (Student, Product, Device Data) | Tamil Technicians

Tamil Technicians – C Programming Course · Structures (struct) in C

Structures in C – Struct with Examples (Student, Product, Device Data)

In C programming, structures (keyword struct) let you group multiple related values under a single name. Instead of keeping separate variables for name, roll number, marks, price, model, voltage, etc., you can keep them neatly inside one structured type.

In this lesson, you will learn:

  • What a struct is and why we need it.
  • How to declare, define and use structures in C.
  • Real-world examples – Student, Product and Device data.
  • Arrays of structures – managing many students/products/devices.
  • Passing structures to functions (by value and by pointer).
  • Using typedef with structs for cleaner code.
  • Nested structures and a quick comparison with union.
Structures in C with student, product and device data examples – Tamil Technicians
Figure: A struct groups related fields like roll number, name, marks or product ID, name, price into a single custom data type.

1. Why Structures? The Problem with Only Basic Types

Imagine you want to store details of a student: roll number, name, and percentage. Using only basic types, you might write:

int rollNo1;
char name1[30];
float percentage1;

int rollNo2;
char name2[30];
float percentage2;

// ... more students

This quickly becomes messy:

  • It’s easy to mix roll numbers and names by mistake.
  • Functions need to receive and return many separate parameters.
  • Managing a list of students becomes hard to handle.
Key idea

A structure lets you combine different pieces of related data into one logical unit – like creating your own custom data type representing a student, a product, or a device.

2. Structure Syntax Basics – Declaring and Using a struct

The general syntax for declaring a structure is:

struct StructName {
    type1 member1;
    type2 member2;
    // ...
};

Example: Student structure

struct Student {
    int   rollNo;
    char  name[30];
    float percentage;
};

This does not allocate memory yet. It only defines a new “pattern” or blueprint named struct Student.

Defining variables of the struct type

int main() {
    struct Student s1;              // single student
    struct Student s2, s3;          // multiple variables

    // Assign values
    s1.rollNo = 101;
    s1.percentage = 86.5f;
    strcpy(s1.name, "Kumar");       // need <string.h> for strcpy

    printf("Roll: %d, Name: %s, Percentage: %.2f\\n",
           s1.rollNo, s1.name, s1.percentage);

    return 0;
}

Access members with the dot operator ., like s1.rollNo.

3. Initializing Structures (Simple & Designated)

You can initialize structures at the time of declaration:

Simple initialization (order matters)

struct Student s1 = {101, "Kumar", 86.5f};

Here, the values follow the member order:

  1. rollNo = 101
  2. name = “Kumar”
  3. percentage = 86.5

Designated (named) initialization (C99)

struct Student s2 = {
    .rollNo = 102,
    .name = "Priya",
    .percentage = 91.0f
};

Designated initializers make code more readable, especially when you have many fields.

4. Memory Layout: How Struct Data Lives in RAM

A structure stores its members one after another in memory (with possible padding). For example:

struct Student {
    int   rollNo;      // 4 bytes
    char  name[30];    // 30 bytes
    float percentage;  // 4 bytes
};

Roughly, the structure size is at least 4 + 30 + 4 = 38 bytes, but due to padding/alignment it may be slightly larger (e.g. 40 bytes) depending on the system.

printf("Size of struct Student = %zu\\n", sizeof(struct Student));
You usually don’t need to worry about padding for basic usage. Just use sizeof(struct Student) to know how much memory a variable of that type occupies.

5. Student Example – List of Students with Array of Structs

Let’s build a small “student list” using an array of structures.

#include <stdio.h>
#include <string.h>

struct Student {
    int   rollNo;
    char  name[30];
    float percentage;
};

int main() {
    struct Student students[3];

    // Fill details
    students[0].rollNo = 101;
    strcpy(students[0].name, "Kumar");
    students[0].percentage = 86.5f;

    students[1].rollNo = 102;
    strcpy(students[1].name, "Priya");
    students[1].percentage = 91.0f;

    students[2].rollNo = 103;
    strcpy(students[2].name, "Ravi");
    students[2].percentage = 78.0f;

    // Print
    int i;
    for (i = 0; i < 3; i++) {
        printf("Roll: %d, Name: %s, Percentage: %.2f\\n",
               students[i].rollNo,
               students[i].name,
               students[i].percentage);
    }

    return 0;
}

This pattern is very common in real-world applications: you maintain a list of records as an array of structs.

6. Product Example – Price, Quantity & Simple Billing

Now consider a small shop or service center that wants to track products:

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

Simple product billing program

#include <stdio.h>
#include <string.h>

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

float calculateTotal(struct Product p) {
    return p.price * p.quantity;
}

int main() {
    struct Product p1;

    p1.id = 1001;
    strcpy(p1.name, "Soldering Iron 60W");
    p1.price = 550.0f;
    p1.quantity = 2;

    float total = calculateTotal(p1);

    printf("Product: %s\\n", p1.name);
    printf("Qty: %d, Price: %.2f\\n", p1.quantity, p1.price);
    printf("Total amount: %.2f\\n", total);

    return 0;
}

Notice how calculateTotal() receives the entire struct Product as a parameter – much cleaner than passing individual values separately.

7. Device Example – Voltage, Current & Status

For technicians, device data is very important. Let’s create a Device structure:

struct Device {
    char  id[20];
    char  location[30];
    float voltage;
    float current;
    int   status;    // 0 = OFF, 1 = ON, 2 = FAULT
};

Reading device data and printing status

#include <stdio.h>
#include <string.h>

struct Device {
    char  id[20];
    char  location[30];
    float voltage;
    float current;
    int   status;    // 0 = OFF, 1 = ON, 2 = FAULT
};

void printDevice(struct Device d) {
    printf("Device ID: %s\\n", d.id);
    printf("Location : %s\\n", d.location);
    printf("Voltage  : %.1f V\\n", d.voltage);
    printf("Current  : %.2f A\\n", d.current);

    if (d.status == 0)      printf("Status  : OFF\\n");
    else if (d.status == 1) printf("Status  : ON\\n");
    else if (d.status == 2) printf("Status  : FAULT\\n");
    else                    printf("Status  : UNKNOWN\\n");
}

int main() {
    struct Device inverter;

    strcpy(inverter.id, "INV-01");
    strcpy(inverter.location, "Block A - Roof");
    inverter.voltage = 230.0f;
    inverter.current = 12.5f;
    inverter.status = 1;  // ON

    printDevice(inverter);

    return 0;
}

This pattern is close to how real monitoring systems hold device data before logging or sending it to a remote server.

8. Passing Structures to Functions – By Value vs By Pointer

You can pass structs to functions in two ways:

  • By value: function gets a copy of the struct.
  • By pointer: function gets the address and can modify the original.

By value – copy only

void printStudent(struct Student s); // copy

Changes inside printStudent will not affect the original Student in main().

By pointer – can modify original

void updatePercentage(struct Student *s, float newPercent) {
    s->percentage = newPercent;   // use arrow operator with pointer
}

Call it as:

updatePercentage(&s1, 90.0f);
The arrow operator -> is shorthand for (*pointer).member. So s->percentage means (*s).percentage.

9. typedef with struct – Cleaner Type Names

Writing struct Student every time is a bit long. You can use typedef to create a shorter name:

typedef struct {
    int   rollNo;
    char  name[30];
    float percentage;
} Student;   // Student is now an alias for this struct

Now you can declare:

Student s1, s2;          // no need to write struct keyword
Student classA[50];

This is very common in real-world C code and makes function signatures cleaner.

10. Nested Structures – Struct Inside Another Struct

You can put one struct inside another to create more detailed records.

Example: Device with nested reading info

typedef struct {
    float voltage;
    float current;
    float power;
} Reading;

typedef struct {
    char    id[20];
    char    location[30];
    Reading latest;   // nested struct
} Device;

Using nested structs

#include <stdio.h>
#include <string.h>

typedef struct {
    float voltage;
    float current;
    float power;
} Reading;

typedef struct {
    char    id[20];
    char    location[30];
    Reading latest;
} Device;

int main() {
    Device d;

    strcpy(d.id, "INV-02");
    strcpy(d.location, "Block B - Roof");

    d.latest.voltage = 228.5f;
    d.latest.current = 13.2f;
    d.latest.power   = d.latest.voltage * d.latest.current / 1000.0f;  // kW approx

    printf("Device %s at %s\\n", d.id, d.location);
    printf("V = %.1f, I = %.1f, P = %.2f kW\\n",
           d.latest.voltage, d.latest.current, d.latest.power);

    return 0;
}

This is powerful for organizing complex real-world data without losing clarity.

11. Struct vs Array vs Union – Quick Comparison

Feature Struct Array Union (for reference)
Types allowed Can contain different types. All elements must be of the same type. Different types, but share same memory.
Memory layout Members stored sequentially (with padding). Elements stored sequentially. All members overlap in the same memory region.
Use case Logical records: student, product, device. List/sequence of similar values. Data that is mutually exclusive; memory saving.
Access obj.member or ptr->member arr[index] Only one member should be valid at a time.

12. Common Mistakes with Structures

  • Forgetting #include <string.h>: Using strcpy, strcat etc. without including the header.
  • Using . instead of -> (or vice versa): Remember: use . with normal variables, -> with pointers.
  • Passing large structs by value unnecessarily: For big structures or performance-sensitive code, pass by pointer.
  • Confusing arrays of structs with struct of arrays: Make sure your design matches how you access the data most often.
Whenever you see struct Something * in a function parameter, imagine that the function is operating directly on the original object from the caller. Changes via -> will be visible outside.

13. Learning Checklist – Structures in C

  • I know how to declare a structure type with the struct keyword.
  • I can create variables and arrays of that struct type.
  • I can use the dot operator . to access members of a struct variable.
  • I can use the arrow operator -> to access members via a struct pointer.
  • I understand when to pass structs by value and when to pass them by pointer.
  • I can design real-world record types like Student, Product, Device using structs.
  • I know how to use typedef to create a shorter name for a struct type.
  • I have seen how nested structs work for more detailed data models.

Suggested Featured Image Prompt

Use this prompt in your AI image generator for the thumbnail of this blog post:

“Flat modern 16:9 illustration on a light background. The screen of a laptop shows C code with three struct definitions: `struct Student`, `struct Product`, and `struct Device`, each with fields like rollNo, name, percentage, id, price, quantity, voltage and current. Next to the laptop, three separate cards are drawn: one labeled ‘Student’ showing icons of a student ID and marks; one labeled ‘Product’ with a box and price tag; and one labeled ‘Device’ with a small inverter icon showing voltage and current values. Lines connect each card back to its corresponding `struct` block on the laptop, representing real data grouped into structures. A South Indian / Tamil technician character points to the screen with a pointer stick. At the top, bold title text: ‘Structures in C’ and smaller subtitle: ‘Student, Product & Device Data | Tamil Technicians’. Clean vector style, minimal colors, educational, high quality.”

FAQ: Structures (struct) in C

1. When should I use a structure in C?

Use a structure whenever you have multiple related values that logically form one “record”: a student with roll number, name and marks; a product with ID, name, price and quantity; a device with voltage, current and status, and so on. Structures keep this related data together.

2. What is the difference between an array and a struct?

An array holds many values of the same type (e.g., 10 integers). A struct holds a small fixed set of values of different types (e.g., int for ID, char[] for name, float for price).

3. Should I pass structs by value or by pointer?

For small structs, passing by value is simple and fine. For larger structs or performance-critical code, prefer passing by pointer, especially if the function needs to modify the original data.

4. Why do people use typedef with structs?

typedef removes the need to repeat the struct keyword everywhere and gives a cleaner type name. For example, typedef struct { ... } Student; lets you write Student s; instead of struct Student s;.

Category: C Programming Course · Lesson – Structures in C (Student, Product, Device Data)

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top