Home C++ C++ Structures tutorial with code examples

C++ Structures tutorial with code examples

In C++, structures (struct) are user-defined data types that allow you to group different types of data together under a single name.

They are especially useful when you want to model complex data that involves multiple fields.

Structures can contain variables of different data types, and they are similar to classes, though by default, their members are public.

Defining and Using Structures

  1. Define Structure: Use the struct keyword, followed by a name and curly braces containing the structure’s members.
  2. Access Members: Use the dot (.) operator to access or modify members of a structure variable.

Let’s explore structures with various examples.

1. Basic Structure Definition and Usage

Define a simple structure and access its members.

#include <iostream>
using namespace std;

// Define a structure called Person
struct Person {
    string name;
    int age;
    double height;
};

int main() {
    // Declare a structure variable
    Person person1;

    // Assign values to members
    person1.name = "Alice";
    person1.age = 25;
    person1.height = 5.5;

    // Display values
    cout << "Name: " << person1.name << endl;
    cout << "Age: " << person1.age << endl;
    cout << "Height: " << person1.height << endl;

    return 0;
}

Explanation:

  • Person is a structure with three members: name, age, and height.
  • We create an instance of Person, person1, and set values for its members.

Output:

Name: Alice
Age: 25
Height: 5.5

2. Initializing Structures

You can initialize structures using an initializer list.

#include <iostream>
using namespace std;

struct Car {
    string make;
    int year;
    double price;
};

int main() {
    // Initialize structure variable with an initializer list
    Car car1 = {"Toyota", 2020, 15000.0};

    // Display values
    cout << "Make: " << car1.make << endl;
    cout << "Year: " << car1.year << endl;
    cout << "Price: $" << car1.price << endl;

    return 0;
}

Explanation:

  • Car is a structure initialized with { “Toyota”, 2020, 15000.0 }, which assigns values to make, year, and price directly.

Output:

Make: Toyota
Year: 2020
Price: $15000

3. Array of Structures

You can create an array of structures to store multiple records.

#include <iostream>
using namespace std;

struct Book {
    string title;
    string author;
    double price;
};

int main() {
    // Array of structures
    Book library[3] = {
        {"The Great Gatsby", "F. Scott Fitzgerald", 10.99},
        {"1984", "George Orwell", 8.99},
        {"To Kill a Mockingbird", "Harper Lee", 7.99}
    };

    // Display book information
    for (int i = 0; i < 3; i++) {
        cout << "Title: " << library[i].title << ", Author: " << library[i].author
             << ", Price: $" << library[i].price << endl;
    }

    return 0;
}

Explanation:

  • library is an array of Book structures containing three records.
  • We use a loop to access and print details of each book.

Output:

Title: The Great Gatsby, Author: F. Scott Fitzgerald, Price: $10.99
Title: 1984, Author: George Orwell, Price: $8.99
Title: To Kill a Mockingbird, Author: Harper Lee, Price: $7.99

4. Structure Pointers and the Arrow Operator

Structure pointers allow efficient handling of large structures and are accessed using the arrow (->) operator.

#include <iostream>
using namespace std;

struct Student {
    string name;
    int grade;
};

int main() {
    Student student = {"John", 90};

    // Pointer to structure
    Student* ptr = &student;

    // Access members using arrow operator
    cout << "Name: " << ptr->name << endl;
    cout << "Grade: " << ptr->grade << endl;

    return 0;
}

Explanation:

  • ptr is a pointer to the Student structure student.
  • The -> operator accesses name and grade members through the pointer.

Output:

Name: John
Grade: 90

5. Structures Within Structures (Nested Structures)

You can nest structures within other structures to create more complex data models.

#include <iostream>
using namespace std;

struct Address {
    string city;
    string state;
    int zip;
};

struct Employee {
    string name;
    Address address;
    double salary;
};

int main() {
    // Initialize nested structure
    Employee employee = {"Jane", {"New York", "NY", 10001}, 70000};

    // Display information
    cout << "Name: " << employee.name << endl;
    cout << "City: " << employee.address.city << endl;
    cout << "State: " << employee.address.state << endl;
    cout << "Zip: " << employee.address.zip << endl;
    cout << "Salary: $" << employee.salary << endl;

    return 0;
}

Explanation:

  • Employee contains an Address structure as a member.
  • The nested structure allows us to group related data (like address details) within a higher-level structure.

Output:

Name: Jane
City: New York
State: NY
Zip: 10001
Salary: $70000

6. Passing Structures to Functions

You can pass structures to functions by value or by reference for efficient handling.

#include <iostream>
using namespace std;

struct Rectangle {
    double length;
    double width;
};

// Function to calculate area (pass by value)
double calculateArea(Rectangle rect) {
    return rect.length * rect.width;
}

int main() {
    Rectangle rect = {10.5, 5.5};
    cout << "Area: " << calculateArea(rect) << endl;

    return 0;
}

Explanation:

  • calculateArea takes a Rectangle structure by value and calculates the area.
  • Passing structures by reference can avoid copying large data if efficiency is a concern.

Output:

Area: 57.75

7. Returning Structures from Functions

A function can return a structure, which is useful for creating and initializing structures within a function.

#include <iostream>
using namespace std;

struct Circle {
    double radius;
    double area;
};

// Function to create a Circle with a given radius
Circle createCircle(double radius) {
    Circle circle;
    circle.radius = radius;
    circle.area = 3.14159 * radius * radius;
    return circle;
}

int main() {
    Circle myCircle = createCircle(5.0);
    cout << "Radius: " << myCircle.radius << endl;
    cout << "Area: " << myCircle.area << endl;

    return 0;
}

Explanation:

  • createCircle returns a Circle structure with a calculated area based on the provided radius.

Output:

Radius: 5
Area: 78.5398

8. Using typedef with Structures

typedef can be used with structures to simplify syntax, especially when using complex or nested structures.

#include <iostream>
using namespace std;

// Define structure with typedef
typedef struct {
    string name;
    int id;
} Employee;

int main() {
    Employee employee = {"Alice", 101}; // Using typedef

    cout << "Name: " << employee.name << endl;
    cout << "ID: " << employee.id << endl;

    return 0;
}

Explanation:

  • typedef allows us to use Employee directly instead of struct Employee, simplifying the code.

Output:

Name: Alice
ID: 101

9. Using Structures in Arrays

Structures can be combined with arrays to create complex collections, such as an array of student records.

#include <iostream>
using namespace std;

struct Student {
    string name;
    int age;
};

int main() {
    // Array of structures
    Student students[3] = {
        {"John", 18},
        {"Alice", 19},
        {"Bob", 20}
    };

    // Display student information
    for (int i = 0; i < 3; i++) {
        cout << "Student " << i + 1 << ": " << students[i].name
             << ", Age: " << students[i].age << endl;
    }

    return 0;
}

Explanation:

  • students is an array of Student structures.
  • Each element in the array represents a Student with name and age members.

Output:

Student 1: John, Age: 18
Student 2: Alice, Age: 19
Student 3: Bob, Age: 20

10. Using Structures in Vectors

Combining structures with vectors provides

a flexible way to manage collections of data with dynamic sizing.

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

struct Product {
    string name;
    double price;
};

int main() {
    vector<Product> products;

    // Add products to vector
    products.push_back({"Laptop", 999.99});
    products.push_back({"Smartphone", 499.99});
    products.push_back({"Tablet", 299.99});

    // Display product information
    for (const auto &product : products) {
        cout << "Product: " << product.name << ", Price: $" << product.price << endl;
    }

    return 0;
}

Explanation:

  • products is a vector of Product structures, allowing dynamic addition of new products.
  • We use a range-based for loop to display each product.

Output:

Product: Laptop, Price: $999.99
Product: Smartphone, Price: $499.99
Product: Tablet, Price: $299.99

Summary Table of Structure Usage

Feature Example Description
Basic Structure struct Person { string name; int age; }; Group multiple data fields
Initializing Structure Person person = {“Alice”, 25}; Initialize structure with values
Array of Structures Person people[3]; Store multiple records of the same structure
Structure Pointers Person* ptr = &person; Access structure with pointer
Nested Structures struct Employee { Address addr; }; Organize complex data with nested structures
Pass by Value void display(Person p); Pass structure as parameter
Pass by Reference void modify(Person &p); Efficiently modify structure data
Returning Structures Person createPerson(); Return structure from a function
typedef with Struct typedef struct { … } Employee; Simplify structure declaration
Vector of Structures vector<Product> products; Manage structures with dynamic resizing

Key Takeaways

  • Structures allow you to group different data types together under a single name, making them ideal for modeling complex data.
  • Structures can be nested, combined with arrays or vectors, and passed to functions by value or reference.
  • Using pointers and the arrow operator lets you efficiently handle structures, especially large ones.
  • typedef and initialization lists simplify structure syntax, and accessibility of members by default is public, unlike in classes.

You may also like