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
- Define Structure: Use the struct keyword, followed by a name and curly braces containing the structure’s members.
- 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.