Paramclasses Academy - Blog

Tutorials Details

What is Structures (struct) in C++

What is Structures (struct) in C++

October 15, 2026

A structure (struct) in C++ is a user-defined type that groups related data items under one name. Instead of storing a student's name, roll number, and marks in separate unrelated variables, you can combine them into one Student structure.

In this module, we’ll learn how to declare structures, initialize objects, access members, work with arrays of structures, pass structures to functions, and build a small student-record program.

1. Learning objectives

By the end of this module, you will be able to:

  • Define a structure using struct.

  • Create structure variables, also called objects or instances.

  • Access and modify members using the dot operator (.).

  • Initialize structures and use default member values.

  • Create arrays of structures.

  • Pass structures to functions by value and by reference.

  • Use pointers to structures and the arrow operator (->).

  • Build a basic student-record management program.

Estimated time

60–90 minutes

Prerequisites

Variables, data types, arrays, loops, functions, and pointers

2. What is a structure?

Suppose you want to store information about a student:

  • Name

  • Roll number

  • Marks

You could declare three separate variables:

string name = "Aman";
int rollNumber = 101;
float marks = 87.5f;

But if you need to store information about 100 students, managing all the separate variables becomes inconvenient.

A structure lets you group related information:

struct Student {
    string name;
    int rollNumber;
    float marks;
};

Now you can create a Student object containing all three fields.

Visual example: one student record

Student object

name

"Aman"

rollNumber

101

marks

87.5

A single Student object groups these three related values.

3. Structure syntax

The general syntax is:

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

Key points:

  • struct is the keyword used to define the structure type.

  • StructureName is the type name you choose.

  • The variables inside the braces are called members.

  • The semicolon after the closing brace is required.

  • The definition creates a type; it does not automatically create a named object.

Example 1 — Define and use a structure


#include <iostream>
#include <string>
using namespace std;

struct Student {
    string name;
    int rollNumber;
    float marks;
};

int main() {
    Student s1;

    s1.name = "Aman";
    s1.rollNumber = 101;
    s1.marks = 87.5f;

    cout << "Name: " << s1.name << endl;
    cout << "Roll Number: " << s1.rollNumber << endl;
    cout << "Marks: " << s1.marks << endl;

    return 0;
}

Output

Name: Aman
Roll Number: 101
Marks: 87.5

Explanation:

  1. struct Student defines a new type.

  2. Student s1; creates an object named s1.

  3. s1.name accesses the name member.

  4. The assignment statements store values in the object's members.

The dot (.) operator is used to access a member through an object.

4. Creating and initializing structure objects

Once you define a structure, you can create multiple objects of that type.

Student s1;
Student s2;
Student s3;

Each object has its own member values. Changing s1.name does not change s2.name.

Example 2 — Multiple structure objects


#include <iostream>
#include <string>
using namespace std;

struct Student {
    string name;
    int rollNumber;
    float marks;
};

int main() {
    Student s1 = {"Aman", 101, 87.5f};
    Student s2 = {"Priya", 102, 92.0f};

    cout << s1.name << " - " << s1.marks << endl;
    cout << s2.name << " - " << s2.marks << endl;

    return 0;
}

Output

Aman - 87.5
Priya - 92

Initialization methods

Method

Example

Meaning

Declare, then assign

Student s1; then assign members

Set member values separately

Brace initialization

Student s1{"Aman", 101, 87.5f};

Initialize members in declaration order

Default member values

int rollNumber = 0; inside the struct

Provide a default value for a member

Example 3 — Default member values


#include <iostream>
#include <string>
using namespace std;

struct Student {
    string name = "Unknown";
    int rollNumber = 0;
    float marks = 0.0f;
};

int main() {
    Student s1;
    Student s2{"Riya", 103, 95.0f};

    cout << s1.name << ", " << s1.rollNumber << endl;
    cout << s2.name << ", " << s2.rollNumber << endl;

    return 0;
}

Output

Unknown, 0
Riya, 103

Default member initializers are helpful when you want objects to start with sensible values.

5. Accessing and modifying members

Use the dot operator (.) to read or update an object's members.

s1.marks = 95.0f;
cout << s1.marks;

Example 4 — Update structure members


#include <iostream>
using namespace std;

struct Product {
    int id;
    double price;
};

int main() {
    Product p{201, 499.99};

    cout << "Old price: " << p.price << endl;

    p.price = 449.99;

    cout << "New price: " << p.price << endl;

    return 0;
}

Output

Old price: 499.99
New price: 449.99

The type definition describes which members each Product object contains. Each object stores its own id and price.

6. Arrays of structures

When you need to store multiple records of the same type, you can create an array of structures.

Syntax

StructureName arrayName[size];

For example:

Student students[3];

This creates an array with three Student objects.

Example 5 — Store and display student records


#include <iostream>
#include <string>
using namespace std;

struct Student {
    string name;
    int rollNumber;
    float marks;
};

int main() {
    Student students[3] = {
        {"Aman", 101, 85.5f},
        {"Priya", 102, 91.0f},
        {"Rahul", 103, 78.5f}
    };

    for (int i = 0; i < 3; i++) {
        cout << "Name: " << students[i].name << endl;
        cout << "Roll: " << students[i].rollNumber << endl;
        cout << "Marks: " << students[i].marks << endl;
        cout << "-----" << endl;
    }

    return 0;
}

Output

Name: Aman
Roll: 101
Marks: 85.5
-----
Name: Priya
Roll: 102
Marks: 91
-----
Name: Rahul
Roll: 103
Marks: 78.5
-----

Remember:

  • students[i] selects one structure object.

  • students[i].name accesses that object's name member.

  • The loop processes all three records.

Find the student with the highest marks


#include <iostream>
#include <string>
using namespace std;

struct Student {
    string name;
    float marks;
};

int main() {
    Student students[] = {
        {"Aman", 85.5f},
        {"Priya", 91.0f},
        {"Rahul", 78.5f}
    };

    int size = 3;
    int highestIndex = 0;

    for (int i = 1; i < size; i++) {
        if (students[i].marks > students[highestIndex].marks) {
            highestIndex = i;
        }
    }

    cout << "Top student: " << students[highestIndex].name << endl;
    cout << "Marks: " << students[highestIndex].marks << endl;

    return 0;
}

Output

Top student: Priya
Marks: 91

This pattern is useful in marksheets, employee databases, inventory systems, and other record-based programs.

7. Passing structures to functions

You can pass a structure to a function in several ways. The most common choices are pass by value and pass by reference.

A. Pass by value

The function receives a separate copy of the structure. Modifying that copy does not modify the original object.


#include <iostream>
#include <string>
using namespace std;

struct Student {
    string name;
    float marks;
};

void displayStudent(Student s) {
    cout << s.name << ": " << s.marks << endl;
}

int main() {
    Student s1{"Aman", 88.5f};

    displayStudent(s1);

    return 0;
}

Output

Aman: 88.5

Use pass by value when you want a function to work with an independent copy. Copying a large structure can be expensive, so consider a reference for larger objects.

B. Pass by reference

A reference parameter refers to the original object. The function can modify it directly.


#include <iostream>
#include <string>
using namespace std;

struct Student {
    string name;
    float marks;
};

void updateMarks(Student& s) {
    s.marks = 95.0f;
}

int main() {
    Student s1{"Aman", 88.5f};

    updateMarks(s1);

    cout << s1.name << ": " << s1.marks << endl;

    return 0;
}

Output

Aman: 95

The & in Student& s declares a reference parameter. Here, it is not the address-of operator used in an expression such as &s1.

C. Pass by constant reference

If a function needs to read a structure without modifying it, const StructureName& is often a good choice.

void displayStudent(const Student& s) {
    cout << s.name << ": " << s.marks << endl;
}

This avoids copying the structure and prevents the function from changing its members through s.

Parameter form

Copies the structure?

Can modify the original through the parameter?

Student s

Yes

No

Student& s

No

Yes

const Student& s

No

No

8. Pointers to structures

A pointer can store the address of a structure object.

Student s1{"Aman", 88.5f};
Student* ptr = &s1;

There are two ways to access a member through the pointer.

cout << (*ptr).name;
cout << ptr->name;

Both expressions access the name member of the object pointed to by ptr. The arrow operator (->) is the more convenient notation.

Example 6 — Use the arrow operator


#include <iostream>
#include <string>
using namespace std;

struct Student {
    string name;
    float marks;
};

int main() {
    Student s1{"Priya", 92.0f};
    Student* ptr = &s1;

    cout << ptr->name << endl;
    cout << ptr->marks << endl;

    ptr->marks = 96.0f;

    cout << "Updated marks: " << s1.marks << endl;

    return 0;
}

Output

Priya
92
Updated marks: 96

The pointer refers to s1, so modifying ptr->marks updates the original object.

9. Nested structures

A structure can contain another structure as a member. This is called a nested structure.

Example 7 — Student with an address


#include <iostream>
#include <string>
using namespace std;

struct Address {
    string city;
    int postalCode;
};

struct Student {
    string name;
    int rollNumber;
    Address address;
};

int main() {
    Student s1{
        "Aman",
        101,
        {"Raipur", 492001}
    };

    cout << "Name: " << s1.name << endl;
    cout << "City: " << s1.address.city << endl;
    cout << "Postal code: " << s1.address.postalCode << endl;

    return 0;
}

Output

Name: Aman
City: Raipur
Postal code: 492001

The expression s1.address.city accesses the city member of the nested Address object.

Nested structures are useful when a record contains related groups of information, such as an employee's address or a product's dimensions.

10. struct vs. class in C++

Both struct and class can define custom types with data members, member functions, constructors, and other features.

The key default difference is access control.

Feature

struct

class

Default member access

public

private

Default inheritance access

public

private

Can contain functions?

Yes

Yes

Can have constructors?

Yes

Yes

Example:

struct Student {
    string name;  // public by default
};

class Account {
    int balance;  // private by default
};

For beginner record types, struct is often convenient because its members are public by default. In larger programs, choose the type and access rules based on the design you need.

11. Mini project — Student record management

Build a small program that stores student records, displays them, calculates the average marks, and identifies the highest-scoring student.


#include <iostream>
#include <string>
using namespace std;

struct Student {
    string name;
    int rollNumber;
    float marks;
};

void displayStudent(const Student& s) {
    cout << "Name: " << s.name << endl;
    cout << "Roll Number: " << s.rollNumber << endl;
    cout << "Marks: " << s.marks << endl;
    cout << "----------------" << endl;
}

int main() {
    Student students[] = {
        {"Aman", 101, 85.5f},
        {"Priya", 102, 91.0f},
        {"Rahul", 103, 78.5f}
    };

    int size = 3;
    float total = 0;
    int highestIndex = 0;

    for (int i = 0; i < size; i++) {
        displayStudent(students[i]);
        total += students[i].marks;

        if (students[i].marks > students[highestIndex].marks) {
            highestIndex = i;
        }
    }

    cout << "Average marks: " << total / size << endl;
    cout << "Top student: "
         << students[highestIndex].name << endl;

    return 0;
}

Expected output

Name: Aman
Roll Number: 101
Marks: 85.5
----------------
Name: Priya
Roll Number: 102
Marks: 91
----------------
Name: Rahul
Roll Number: 103
Marks: 78.5
----------------
Average marks: 85
Top student: Priya

Project breakdown

  1. The Student structure defines the fields for a student record.

  2. The students array holds three records.

  3. displayStudent() receives each record by constant reference.

  4. The loop calculates the total marks and finds the highest-scoring student.

  5. total / size calculates the average.

Extension challenges

Once the basic project works, add these features:

  • Ask the user to enter student details with cin and getline.

  • Search for a student by roll number.

  • Print only students who scored at least 80 marks.

  • Sort students by marks from highest to lowest.

  • Add a letter grade based on each student's marks.

12. Common mistakes

Mistake 1 — Missing semicolon

Incorrect:

struct Student {
    int rollNumber;
}

Correct:

struct Student {
    int rollNumber;
};

A structure definition requires a semicolon after its closing brace.

Mistake 2 — Using the wrong member operator

Student s1{"Aman", 90};
// s1->marks;  // Wrong for an object

Use s1.marks for an object. Use ptr->marks for a pointer to a structure.

Mistake 3 — Confusing a type with an object

struct Student {
    int rollNumber;
};

Student s1;  // Creates an object

Defining Student creates a type; declaring s1 creates an object.

Mistake 4 — Assuming a local structure is automatically initialized

struct Record {
    int value;
};

Record r;

In this example, r.value is not automatically initialized to zero. Initialize the object explicitly, for example Record r{};, or provide a default member initializer.

Mistake 5 — Accidentally modifying a record

If a function only needs to display a record, prefer:

void display(const Student& s);

The const reference avoids copying and prevents modifications through that parameter.

13. Hands-on exercises

Try these tasks yourself before revealing the solutions.

Exercise 1 — Book structure

Create a Book structure with title, author, and price. Create one book object and print all its details.

Exercise 2 — Rectangle area

Create a Rectangle structure with length and width. Write a function that returns its area.

Exercise 3 — Employee array

Create an Employee structure with name and salary. Store three employees in an array and display the employee with the highest salary.

Exercise 4 — Pass by reference

Create a Product structure with a price member. Write a function that takes a Product& and applies a 10% discount.

Exercise 5 — Nested structures

Create an Address structure with city and postalCode, then include it inside an Employee structure. Print the employee's city.

Show exercise solutions

14. Interactive knowledge-check quiz

Test your understanding of C++ structures. Read each question carefully and check the feedback after submitting.

Given struct Student { int roll; }; and Student s{101};, which expression accesses the roll member?

1 of 8

As.roll

BStudent.roll

Cs->roll

Droll.s

Next

15. Module 10 completion checklist

Your progress

0 of 10

Define a structure with the struct keyword.

Create and initialize multiple structure objects.

Read and update members using the dot operator.

Use arrays of structures and loop through records.

Pass structures by value and by reference.

Use const references for read-only function parameters.

Access structure members through pointers using ->.

Create and access nested structures.

Explain the default access difference between struct and class.

Complete the student record management mini project.