Structures in C — Complete Lesson
0%
C Programming  ·  Chapter 9

Structures in C

Your own custom data type — group related variables of different types under one name. Explained simply with real examples, visuals, and programs.

What is a structure
struct keyword
. dot operator
Array of structures
typedef
Nested structures
5 programs
§1

What is a Structure? — The Big Idea

Concept

So far you have learned about arrays — but an array can only hold one type of data. All ints, or all floats, or all chars. But real-world things have mixed data.

Think about a student. A student has:

  • a name — that's a string (char array)
  • a roll number — that's an int
  • a marks — that's a float
  • an age — that's an int

You cannot store all of this in one array — they are different types! A structure is C's solution. It lets you create your own custom data type that groups different types of variables together under one name.

Think of it like a form. When you fill out a school admission form, every student fills in the same boxes — Name, Age, Address, Marks. Each box holds a different type of information. A structure in C is exactly like that form — you define the boxes once, then fill them in for each student.

Before structures, you'd need 4 separate arrays for 5 students:

  • char names[5][20], int rollNo[5], float marks[5], int age[5]
  • These are linked only by index. Hard to manage, easy to lose track.

With a structure: Student s[5] — one array, all data bundled together. s[0] has its own name, roll number, marks, and age all in one place.

defining a structure
§2

Defining a Structure — The struct Keyword

Syntax

Defining a structure is like creating a blueprint. The definition itself creates no variables and uses no memory. It just tells C: "here is the shape of this new type — what fields it has and what type each field is."

Syntax — defining a structure
struct  tag_name  {
    data_type  member1;
    data_type  member2;
    data_type  member3;
};                          ← semicolon is required!

/* Example */
struct Student {
    char  name[20];
    int   rollNo;
    float marks;
    int   age;
};
struct Student — a blueprint with 4 fields
struct Student
char[20]
name
student's full name
int
rollNo
unique roll number
float
marks
total marks scored
int
age
age in years
definition only — no memory yet
char[20] for the name string
int for whole number
float for decimal
int for whole number
Semicolon after the closing brace! struct Student { ... }; — the ; after } is required. Unlike functions, struct definitions must end with a semicolon. Forgetting this is the most common beginner mistake.
creating variables
§3

Declaring Variables — The . Dot Operator

Access members

The struct definition is just the blueprint. To actually store data, you declare a variable of that struct type. Then to access any field inside it, you use the dot operator . — written as variable.member.

Read it as: "the name field of s1" → s1.name. "The marks of s1" → s1.marks.

Declaring a struct variable
struct Student s1;          /* declares ONE variable of type Student */
struct Student s1, s2, s3;  /* declares THREE variables */

/* Access and assign members using the dot operator */
s1.rollNo = 101;
s1.age    = 18;
s1.marks  = 87.5;
strcpy(s1.name, "Ananta");  /* strings need strcpy, not = */
struct Student s1 — after assigning values
s1 (struct Student)
char[20]
s1.name
"Ananta"
int
s1.rollNo
101
float
s1.marks
87.5
int
s1.age
18
struct_basic.c
C
#include <stdio.h>
#include <string.h>

/* Step 1 — Define the structure (the blueprint) */
struct Student {
    char  name[20];
    int   rollNo;
    float marks;
    int   age;
};

int main() {
    /* Step 2 — Declare a variable of that type */
    struct Student s1;

    /* Step 3 — Assign values using dot operator */
    strcpy(s1.name, "Ananta");  /* strings use strcpy */
    s1.rollNo = 101;
    s1.marks  = 87.5;
    s1.age    = 18;

    /* Step 4 — Read and print */
    printf("Name    : %s\n",  s1.name);
    printf("Roll No : %d\n",  s1.rollNo);
    printf("Marks   : %.1f\n", s1.marks);
    printf("Age     : %d\n",  s1.age);

    return 0;
}
output
Name    : Ananta
Roll No : 101
Marks   : 87.5
Age     : 18
Why strcpy for strings but = for others? In C, you can't assign strings with = after declaration. s1.name = "Ananta" is an error. Always use strcpy(s1.name, "Ananta"). For int, float, char — the plain = works fine.
initialisation
§4

Initialising a Structure — At Declaration

Shortcut

Just like an array, you can give a structure its values right at the moment of declaration. List the values in the same order as the members are defined, inside curly braces.

struct_init.c
C
#include <stdio.h>

struct Point {
    int x;
    int y;
};

struct Book {
    char  title[30];
    char  author[20];
    int   pages;
    float price;
};

int main() {
    /* Initialise at declaration — values in order */
    struct Point p1 = {3, 7};

    struct Book b1 = {
        "Let Us C",
        "Yashavant Kanetkar",
        680,
        350.00
    };

    printf("Point  : (%d, %d)\n", p1.x, p1.y);
    printf("Title  : %s\n",      b1.title);
    printf("Author : %s\n",      b1.author);
    printf("Pages  : %d\n",      b1.pages);
    printf("Price  : Rs %.2f\n", b1.price);

    return 0;
}
output
Point  : (3, 7)
Title  : Let Us C
Author : Yashavant Kanetkar
Pages  : 680
Price  : Rs 350.00
array of structures
§5

Array of Structures — Store Many Records

Most useful feature

This is where structures become truly powerful. Just like int numbers[5] stores 5 integers, struct Student s[5] stores 5 complete student records. Each element of the array is a full struct — with its own name, rollNo, marks, and age.

Access: s[0].name is the name of the first student. s[2].marks is the marks of the third student. Array index first, then dot, then member name.

struct Student s[3] — three complete records side by side
s[0]
name
"Ananta"
rollNo
101
marks
87.5
s[1]
name
"Priya"
rollNo
102
marks
92.0
s[2]
name
"Rahul"
rollNo
103
marks
65.5
s[0].marks = 87.5  ·  s[1].name = "Priya"  ·  s[2].rollNo = 103
array_of_structs.c
C
#include <stdio.h>
#include <string.h>

struct Student {
    char  name[20];
    int   rollNo;
    float marks;
};

int main() {
    /* Array of 3 students — initialise all at once */
    struct Student s[3] = {
        {"Ananta", 101, 87.5},
        {"Priya",  102, 92.0},
        {"Rahul",  103, 65.5}
    };
    int   i, topIdx = 0;

    /* Print all students */
    printf("%-10s %-8s %s\n", "Name", "Roll", "Marks");
    printf("-----------------------------\n");
    for (i = 0; i < 3; i++)
        printf("%-10s %-8d %.1f\n",
               s[i].name, s[i].rollNo, s[i].marks);

    /* Find topper */
    for (i = 1; i < 3; i++)
        if (s[i].marks > s[topIdx].marks)
            topIdx = i;

    printf("\nTopper: %s (%.1f)\n",
           s[topIdx].name, s[topIdx].marks);

    return 0;
}
output
Name       Roll     Marks
-----------------------------
Ananta     101      87.5
Priya      102      92.0
Rahul      103      65.5

Topper: Priya (92.0)
s[topIdx].marks — this is the full power of struct arrays. One variable topIdx gives you access to everything about that student: s[topIdx].name, s[topIdx].rollNo, s[topIdx].marks. No need for 3 separate arrays and index tracking.
typedef
§6

typedef — Remove the struct Keyword

Cleaner code

Every time you declare a struct variable you have to write struct Student s1. The word struct is required. This gets repetitive. typedef lets you create a shorter alias — after that you just write Student s1 with no struct needed.

Without typedef
must write struct every time
no_typedef.c
struct Student {
    char name[20];
    int  rollNo;
};

struct Student s1;
struct Student s2;
struct Student arr[5];
With typedef
write Student directly
with_typedef.c
typedef struct {
    char name[20];
    int  rollNo;
} Student;

Student s1;          /* cleaner! */
Student s2;
Student arr[5];
typedef_example.c
C
#include <stdio.h>
#include <string.h>

/* typedef — Student is now a type name like int or float */
typedef struct {
    char  name[20];
    int   rollNo;
    float marks;
} Student;

/* typedef for other types too */
typedef struct {
    int x;
    int y;
} Point;

int main() {
    Student s1;           /* no 'struct' keyword needed */
    Point   p1 = {5, 8};  /* clean! */

    strcpy(s1.name, "Sneha");
    s1.rollNo = 105;
    s1.marks  = 95.0;

    printf("%s — Roll %d — %.1f marks\n",
           s1.name, s1.rollNo, s1.marks);
    printf("Point: (%d, %d)\n", p1.x, p1.y);

    return 0;
}
output
Sneha — Roll 105 — 95.0 marks
Point: (5, 8)
nested structures
§7

Nested Structures — Struct Inside a Struct

Advanced

A structure can contain another structure as one of its members. This is called a nested structure. For example, a Student has a date of birth — which has day, month, and year. Instead of adding three separate fields, you nest a Date struct inside Student.

Access nested members using two dots: s1.dob.day, s1.dob.month, s1.dob.year.

nested_struct.c
C
#include <stdio.h>
#include <string.h>

/* Inner structure — must be defined first */
struct Date {
    int day;
    int month;
    int year;
};

/* Outer structure — contains Date as a member */
struct Student {
    char        name[20];
    int         rollNo;
    struct Date dob;     /* nested — Date inside Student */
    float       marks;
};

int main() {
    struct Student s1;

    strcpy(s1.name, "Vikram");
    s1.rollNo   = 104;
    s1.marks    = 78.5;

    /* Access nested members with TWO dots */
    s1.dob.day   = 15;
    s1.dob.month = 8;
    s1.dob.year  = 2005;

    printf("Name    : %s\n",          s1.name);
    printf("Roll No : %d\n",          s1.rollNo);
    printf("DOB     : %02d/%02d/%d\n",
           s1.dob.day, s1.dob.month, s1.dob.year);
    printf("Marks   : %.1f\n",         s1.marks);

    return 0;
}
output
Name    : Vikram
Roll No : 104
DOB     : 15/08/2005
Marks   : 78.5
Two dots for nested access: s1.dob.day — read it as "the day field inside the dob field of s1". The inner struct must be defined before the outer one uses it.
real program
§8

Complete Program — Phone Contacts Book

Practical example

A mini contacts book — stores 4 contacts with name, phone, and city. Displays all contacts in a table and searches by name. This shows structures doing real useful work.

contacts_book.c
C
#include <stdio.h>
#include <string.h>

typedef struct {
    char name[20];
    char phone[12];
    char city[15];
} Contact;

int main() {
    /* 4 contacts stored in array of structs */
    Contact book[4] = {
        {"Ananta",  "9876543210", "Haridwar"},
        {"Priya",   "8765432109", "Delhi"},
        {"Rahul",   "7654321098", "Mumbai"},
        {"Sneha",   "6543210987", "Pune"}
    };
    int  i, found = -1;
    char search[20];

    /* Display all contacts */
    printf("%-12s %-13s %s\n", "Name", "Phone", "City");
    printf("--------------------------------------\n");
    for (i = 0; i < 4; i++)
        printf("%-12s %-13s %s\n",
               book[i].name, book[i].phone, book[i].city);

    /* Search by name */
    printf("\nSearch contact: ");
    scanf("%s", search);

    for (i = 0; i < 4; i++)
        if (strcmp(book[i].name, search) == 0)
            found = i;

    if (found != -1)
        printf("Found: %s — %s — %s\n",
               book[found].name, book[found].phone, book[found].city);
    else
        printf("Contact not found.\n");

    return 0;
}
output
Name         Phone         City
--------------------------------------
Ananta       9876543210    Haridwar
Priya        8765432109    Delhi
Rahul        7654321098    Mumbai
Sneha        6543210987    Pune

Search contact: Priya
Found: Priya — 8765432109 — Delhi
quick reference
§9

Quick Reference — Everything in One Table

Summary
TaskSyntaxExample
Define structstruct Name { members; };struct Student { char name[20]; int age; };
Declare variablestruct Name var;struct Student s1;
typedef shortcuttypedef struct { ... } Name;typedef struct { int x; int y; } Point;
Assign membervar.member = value;s1.age = 18;
Assign stringstrcpy(var.str, "text");strcpy(s1.name, "Ananta");
Read memberprintf("%d", var.member);printf("%s", s1.name);
Array of structsstruct Name arr[N];struct Student s[5];
Array + dotarr[i].members[2].marks = 90.5;
Nested structouter.inner.members1.dob.year = 2005;
Initialisestruct Name v = {val1, val2};Point p = {3, 7};
quiz
Q

Quick Quiz

Question 1 of 5

What is wrong with this code? struct Car { char brand[10]; int year; }

Question 2 of 5

You have struct Student s1;. How do you assign the name "Rahul" to s1?

Question 3 of 5

What does typedef do when used with a struct?

Question 4 of 5

For struct Student s[5], how do you access the marks of the 3rd student?

Question 5 of 5

A struct Student has a nested struct Date dob. How do you set the year to 2005?

Lesson Checklist

  • A struct groups different types of data under one name — like a form
  • Struct definition ends with a semicolon after the closing brace: };
  • The definition is just a blueprint — no memory is allocated until you declare a variable
  • Use the dot operator (.) to access struct members: s1.name, s1.age
  • Strings inside structs must use strcpy() — not the = operator
  • Array of structs: struct Student s[5] — access with s[i].member
  • typedef lets you write Student s1 instead of struct Student s1
  • Nested struct access uses two dots: s1.dob.year
  • I completed the quiz