A data structure is a group of data elements. Each element inside the data structure is known as member, which can vary from types and different lengths. To declare a data structure, you use the syntax:
Main Syntax
struct type_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
...
} object_names;Alternative Syntax (type name is optional)
There is also another syntax for struct, which only switches the type_name and group of data elements together. (They still work the same, but type_name no longer exists)
You’re still giving the structure to the objects. However, if you were to make another object after line 6 with the same struct, there’s no way to refer to it (use it as a type) unless you use the main syntax above.
struct {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
...
} object_names;Member type and name follow a similar format as variables Variables and types except that they are not initially assigned to a value.
In C++, member type is a type and member name is an identifier.
For example:
struct receipt {
int id;
string payee;
double total;
boolean paid;
};
// Using the struct as a type
receipt invoiceOne, invoiceTwo;In the example, it created a struct receipt, which defined the four members: id, payee, total, & paid. Using this struct, it becomes possible to refer it as a type. In line 9, it constructed a variable that follows the type receipt. With the variables invoiceOne and invoiceTwo, they become objects to the structure.
Alternatively, it is possible to assign the objects in line 6 if you were to remove line 9.
struct receipt {
int id;
string payee;
double total;
boolean paid;
} invoiceOne, invoiceTwo;invoiceOne & invoiceTwo objects STILL maintain the same data structure.
Differentiating structure names and object names
Object names are declared with a specific structure type whereas structure name is an identifier for a group of data elements with types. There could be multiple objects declared from a single data structure.
Once objects are declared from a specific structure type, their members are accessible. Using a dot/period (.) after the object name then follow a specific member name within that same structure will retrieve the member value of that specific member name.
invoiceOne.id; // Gets the member value of id in invoiceOne
invoiceTwo.payee; // Gets the member value of payee in invoiceTwo
invoiceOne.total; // Gets the member value of total in invoiceOne
invoiceTwo.paid; // Gets the member value of paid in invoiceTwoHere’s an example of a use case for structure:
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
using namespace std;
struct membership {
int id;
string owner;
double monthlyCost;
time_t expiresOn;
};
void printGymMembership(membership ms) {
cout << "========" << endl;
cout << ms.owner << " [" << ms.id << "]" << endl;
cout << "Monthly cost: $" << ms.monthlyCost << endl;
cout << "Expires on: " << ms.expiresOn << endl;
cout << "========" << endl;
};
int main() {
time_t currentTime;
vector<membership> listOfMs;
membership ms1;
ms1.owner = "Alejandro";
ms1.id = listOfMs.size() + 1;
ms1.monthlyCost = 25;
ms1.expiresOn = time(¤tTime) + (86400 * 30);
listOfMs.push_back(ms1);
printGymMembership(ms1);
membership ms2;
ms2.owner = "Sabrina";
ms2.id = listOfMs.size() + 1;
ms2.monthlyCost = 10;
ms2.expiresOn = time(¤tTime) + (86400 * 30);
listOfMs.push_back(ms2);
printGymMembership(ms2);
return 0;
}Throughout this example, it has become possible to assign values to the members of an object. Each member of an object serves the same functionality as variables by assigning a value with the assignment operator. When creating a struct membership, the example constructed a variable ms1 with the type membership in line 30 so that we could start filling in the values for each member (owner, id, monthlyCost, & expiresOn). And the same goes for ms2.
The key component of data structures is referring to a member of an object or the structure as a whole. Like in the example, we used membership as a type for vector and assigned a value to each member of the two membership objects (ms1 & ms2).
After assigning values to the members of the two membership objects, the example printed out the information of the members in every gym membership object.
Pointers to structures
A structure pointer is a pointer variable that stores the memory address of a structure. It allows to point to objects of the structure type. This is the syntax for the struct pointer:
struct struct_name *ptr_name;Here’s an example:
struct Device {
int batteryLevel;
string name;
};
// Creating a struct variable
Device iPhone = {100, "16"};If you were to create a pointer to that struct, it would be like this:
struct Device *ptr = &iPhone;
ptr = &iPhone;
// Same as struct Device *ptr = &iPhone;This example shows that ptr is initialized to make a pointer to the struct Device. And ptr is assigned to the object iPhone with & (knowing that we are going to reference the object). &iPhone is a memory address.
Using that pointer, you can pass the values to the object or read the values of the object with the (->) arrow operator
#include <stdio.h>
ptr -> name = "14";
printf("%d", ptr -> batteryLevel);This operator is similar to (*ptr).batteryLevel. Either syntax of the pointer operation works the same. It is not the same with *ptr.
(*ptr).batteryLevel is not the same as (*ptr.batteryLevel)
(*ptr.batteryLevel) doesn’t exist hypothetically because ptr.batteryLevel isn’t a pointer as in the structure, it is an integer type.
| Expression | What is evaluated | Equivalent |
|---|---|---|
a.b | Member b of object a | |
a->b | Member b of object pointed to by a | (*a).b |
*a.b | Value pointed to by member b of object a | *(a.b) |
| imported from C++ documentation |
Important Use Cases
Struct pointers are useful when:
:LiSquareCheck: You are avoiding to copy large amounts of data ⇒ Program uses less memory and become more efficient
:LiSquareCheck: You want to change values inside a function ⇒ Passing struct pointers to the function allows the program to change their original
Nesting structures
Structures could nest on top of each other by using a structure type as a data element type.
struct hobbies_t {
string name;
string description;
}
struct friends_t {
string name;
int age;
hobbies_t mainHobby;
} alejandro, sakura, ophelia;
friends_t * p_friends = &ophelia;| Possible declarations | |
|---|---|
| alejandro.name | member name of the object alejandro |
| sakura.mainHobby | member mainHobby of the object sakura |
| ophelia.mainHobby.name | string name of the member mainHobby of the object ophelia |
| sakura.mainHobby.description | string description of the member mainHobby of the object sakura |
Examples
1. Passing Struct Pointers to Functions
#include <iostream>
#include <string>
using namespace std;
struct franchise {
string name;
string description;
int maxPopulation;
};
void setupFranchise(struct franchise *fran) {
fran -> name = "McDonalds";
fran -> description = "A fast food restaurant";
fran -> maxPopulation = 100;
};
void printFranchise(struct franchise *fran) {
cout << "==================\n";
cout << fran -> name << "\n";
cout << "\"" << fran -> description << "\"";
cout << "\n\nMax Population: " << fran -> maxPopulation << "\n";
cout << "==================";
};
int main() {
struct franchise mcDo;
setupFranchise(&mcDo);
printFranchise(&mcDo);
return 0;
}See more practice
- https://www.w3schools.com/cpp/exercise.asp?x=xrcise_structs1
- https://www.w3schools.com/c/exercise.php?x=xrcise_structs_pointers1
- https://www.geeksforgeeks.org/quizzes/cpp-structures-and-unions/
tl;dr
object_of_that_struct_name.member_nameaccesses the member of the object for that specific structure- modify member values with an assignment operator
- using structure types for member types of a structure allows nesting structures