Structs in C and C++

Explanation of structs in c, how they are a sort of a generalized array. How the members of a struct are accessed.

Last Reviewed and Updated on February 7, 2020
Posted by Parveen(Hoven),
Aptitude Trainer and Software Developer

My C/C++ Videos on Youtube

Here is the complete playlist for video lectures and tutorials for the absolute beginners. The language has been kept simple so that anybody can easily understand them. I have avoided complex jargon in these videos.

Object Oriented Programming is done with the help of structures called struct, classes and unions. All three of them are used to package data and functions into one unit. They have slight differences in their packaging, but the basic point is that they can pack functions and data into one unit. From a layman's perspective, it is like putting the CPU code, SD Card, etc., into one unit called mobile phone.

Packaging Data

Recall from a previous chapter that an array is used to package data under the array identifier name. All the elements of the array are contiguous, and all of them have to be of the same type. An array can be an array of int only, or can be of float only, and so on, but all the elements must be of the same type.

It is possible to package heterogenous data of mixed types under one identifier. The data can be packed in the same contiguous manner as in an array. For this C provides a data structure called struct. A struct can be used to pack mixed types under one identifier. You can pack an int and a char under one identifier. The data items will still share a common wall.

When you begin to package your data into a struct, you face an immediate problem of defining the order. Which item comes first in the layout? Whether your int will be the first to be laid, or will it be the char that would be laid first? This problem doesn't arise in the case of an array. An array contains the same type of units.

So basically, there has to be a concrete map when you want to package heterogenous or mixed types of variables. C allows you to easily define your own custom layout, in whatever fashion you like, and as per your own requirements. You can create a new type synthesized out of existing types, and by arranging and ordering them in a given sequence. Such types are called User Defined Types or UDT for short.

Struct is a UDT because it is based on the map decided by a software developer. This map is defined by using the struct keyword. Here is a definition of a struct called SMyStruct. You must be aware of the fact that it is just a definition. It is a description of the layout. It is only a map. No int or char is created by this defintion. The only thing that it is speaking is that a data structure called SMyStruct will consist of an int and a char, with the int coming before, and the char after.

struct SMyStruct
{
    int i;
 
    char c;
};


The process of actually laying the data members of a struct involves the creation of an object of this struct. Here's the complete code -

struct SMyStruct
{
    int i;
 
    char c;
};
 
int main()
{
    SMyStruct obj = { 34, 'A' };
 
    return 0;
}
 

The identifier "obj" is a heterogenous or mixed data that contains an int i, and a char c. The intializer block above gives 34 to i, and the char c receives 'A'. Please also note that even though obj is a sort of an array, the square brackets are not used here. The square brackets are by default used for arrays of homogenous items. The type of packaging is determined with the help of the struct definition.

Reading and Writing the Packed Data

In the above example, int i and char c are called data members. It is possible to access them by their identifier names. As we have already explained above, the square brackets cannot be used to access the members of a struct. They can only be used with arrays.

Below is a code that shows how to print the values of i and c.

struct SMyStruct
{
    int i;
 
    char c;
};
 
int main()
{
    SMyStruct obj = {34, 'A'};
 
    cout << obj.i << endl;
 
    cout << obj.c << endl;
 
    return 0;
}
 

The same technique can be used to set the values of i and j, and display them back to the screen. The code below shows how to do this.

struct SMyStruct
{
    int i;
 
    char c;
};
 
int main()
{
    SMyStruct obj;
 
    cin >> obj.i;
 
    cin >> obj.c;
 
    cout << obj.i << endl;
 
    cout << obj.c << endl;
 
    return 0;
}

The Location of the struct and it's Data Members

It's quite interesting to display the location of an object of a struct, and it's data members. We expect the address of the object, and the address of the first data member to be same, because the struct starts with the first data member.

struct SMyStruct
{
    int i;
 
    char c;
};
 
int main()
{
    SMyStruct obj;
 
    cout << "address of obj = " << (int)&obj << endl;
 
    cout << "address of obj.i = " << (int)&obj.i << endl;
 
    cout << "address of obj.c = " << (int)&obj.c << endl;
 
    return 0;
}

// output for my machine
address of obj = 1439588
address of obj.i = 1439588
address of obj.c = 1439592 


The output of the above code shows that the address of the struct and of the first member, i, is the same location. Then we also see that the second member, c is laid four spaces away from i. The size of an int on my compiler is 4 bytes, so we have verified that c and i are contiguous.

The sizeof Operator and structs

How much memory does the above struct need? We would expect it to be the sum of memory needed for i, and that needed for c. So we would expect it to be: 4 + 1 = 5 bytes. A compiler doesn't follow this calculation. It can add a padding to a struct to improve performance, and also to generate a correctly aligned executable. This padding is also called data structure alignment. So the conclusion is that the actual sizeof a struct is greater than or equal to the sum of sizes of its data members.

struct SMyStruct
{
    int i;
 
    char c;
};
 
int main()
{
    SMyStruct obj;
 
    cout << "sizeof obj = " << sizeof (obj) << endl;
 
    cout << "sizes of data members = ";
    
    cout << (sizeof (int) + sizeof (char)) << endl;
 
    return 0;
}
 
// output on my machine
// sizeof obj = 8
// sizes of data members = 5
 

Notes on Encapsulation

Encapsulation is one of the core concepts of object oriented programming. It can be understood through an analogy with a mobile phone. The internal circuit along with the memory are packaged into the phone casing and fastened with the screws. There is a sort of protection from the outside environment. The whole purpose of this protection is to prevent accidental damage to the internals so that the device continues to do its job well.

Functions inside a Struct

Before we begin to understand the concept of encapsulation, as applied to a struct, let us first see how can a function be packaged inside a struct. Does it make sense, in the first place? Consider the code below. The struct definition now includes a function also.

struct SMyStruct
{
    int i;
 
    char c;
 
    void show()
    {
        cout << "i = " << i << endl;
 
        cout << "c = " << c << endl;
    }
};
 
int main()
{
    SMyStruct obj = {99, 'A'};
 
    obj.show();
 
    return 0;
}
 

The function displays the values of its peer data members. The function has been called by using the dot operator on the object. The function prints the values of the data members of the very same object on which it has been called. If we created two objects of the struct, both intitialized to different values, and called the function on them, we would receive different outputs because the function prints the values contained inside the respective objects. The code below shows the whole concept.

struct SMyStruct
{
    int i;
 
    char c;
 
    void show()
    {
        cout << "i = " << i << endl;
 
        cout << "c = " << c << endl;
    }
};
 
int main()
{
    SMyStruct obj = {99, 'A'};
 
    SMyStruct obj2 = {-7, 'Z'};
 
    obj.show();
 
    obj2.show();
 
    return 0;
}

When a function is packaged with the data members, it acts on the data members of the object on which it is called. And when we define a struct we have to write the function in the body of the struct, alongside other data members.

Preventing Access to the Data Members

If we can write functions to act on the data members of a struct, and we can write functions to both read and write to them, or, perhaps, perform any custom processing on them, then it makes sense to give exclusive access only to the peer functions. The data members should be be written and read and processed only through the member functions. There should not be any other means or mechanism or window for accessing them, either for reading or writing. This will help in "unity of command". Moreover, this will help us administrate and control the behaviour of an object because data integrity can be guaranteed. And once the data integrity is assured, the behaviour of that object can be guaranteed as well, just like the behaviour of a packed mobile phone.

There is one keyword that can instantly block access to the outside world: private. The code below shows the whole story.

struct SMyStruct
{
    int i;
 
private: char c;
 
public:
    void show()
    {
        cout << "i = " << i << endl;
 
        cout << "c = " << c << endl;
    }
};
 
int main()
{
    SMyStruct obj;
 
    obj.i = 99;
 
    // COMPILER ERROR
    obj.c = 'A';
 
    return 0;
}
 

The use of the private keyword in front of char c is sufficient to encapsulate the data member. The compiler gives an error, when trying to access it from main. There are two more things that you should observe here -

  1. The use of the public keyword against the function. If didn't use this keyword, the function "show" would be a private function. An access-specifier continues to "apply" to succeeding members, until another one is applied to stop it.
  2. The function "show" can access the private data member, char c, because both of them are a part of the same struct. The access-specifiers are used only for encapsulation from the external environment.

Encapsulation and Access Specifiers

Encapsulation in C++ is achieved with the help of access specifiers: public, private, protected. Right now we are concerned about the first two of them. The default access of a member inside a struct is public. So in all our previous examples, when we didn't use any specifiers, the default access was public. That's why we were able to access our int i, and char c from the main function, and everything compiled successfully.

Construction of an object

Why do we write classes and structs? It's not just about packaging data. There's more to it: they have life, they are living objects. They have a behaviour, and they are there for doing something for us, for making our life easier. Each class or a struct has a set of public functions that can be called to do something meaningful for us. A class can draw a picture from a png file, or it can read an mp4 file to play a video for us.

Class and Struct

Before we proceed any further let us first get introduced to the "class" keyword. A class is used to define a data structure, just like a "struct". It is exactly the same as a struct, except for the single difference that the default access inside a class is private, where as it is public inside a struct. There is no other difference at all. The struct keyword has come from the C language. A struct is only a data store in C. It cannot contain any functions. It is just a compact packing of mixed or heterogenous data. The keyword class was introduced in C++, and it can contain functions also. When a struct is used in C++, it can contain functions also. So "struct" is a sort of an evolution link between C and C++.

Even though a struct can contain functions in C++, most developers still prefer to use it as a data store only. The "class" is used to define objects that have behaviour, and can be used to do useful things. Here is a very simple class that has one data member and two functions. This class is called "Print". It has one function to intialize the data memer, int i, and another function to display the value of i.

class Print
{
    int i;
 
public:
    void init (int x)
    {
        i = x;
    }
 
public:
    void show()
    {
        cout << "i = " << i << endl;
    }
};
 
int main()
{
    Print pr;
 
    pr.init(9);
 
    pr.show();
 
    return 0;
}
 

Inside main we have created an object of this class, and called the functions on that object.

Seeding a Class

A class object is created so that it can do something for us. It might be used for doing something as simple as printing a number or as complex as rendering a video. In any case, the guarantee of achieving the correct output depends only on integrity of the data contained inside that object. Yes, its true that we can use correct access specifiers to ensure that the data is not altered through un-authorized channels, but what about ensuring that the object gets the initial or seed values with guarantee? If we have no mechanism to force the initialization of an object, then no matter how correctly we use our access specifiers, the correctness of the end-result cannot be guaranteed. Can an operating system be installed on an un-formatted hard disk?

Display using a Class

Write a function called show() in a class to display "Learn C/C++ from HOVEN TRAININGS", and call this function from main using an object of the class
#include<iostream>
#include<cstdio> 
 
using namespace std;
 
class hoven
{
    
public: 
    
    void show()
    {

        cout << " Learn C/C++ from HOVEN TRAININGS ";

    } 
        
};
 
int main()
{ 
 
    hoven obj;
    
    obj . show();
        
    return 0;
            
}
 

Area of a Rectangle

Program to find area of rectangle using a function within a class, take dimensions as 5 and 6.
#include<iostream>
#include<cstdio> 
 
using namespace std;
 
class CRectangle
{
    
private : int i , j;
    
public : 
    void set_values(int x, int y)
    {
                    
        this->i = x ;
                    
        this->j = y ;
                    
    }
    
public : 
    int area()
    {
                    
         return this->i * this->j;
                     
    }                
                
};
 
int main () 
{
    
    CRectangle rect;
     
    rect.set_values (5,6);
     
    cout << "Rect area: " << rect.area() << endl;
     
    return 0;
            
}
 

Display a Variable

Write a program to display a variable by using a function in a class. Create one function to get input and second function to display the value
#include<iostream>
#include<cstdio> 
 
using namespace std;
 
class programming
{
    
private: int variable;
 
public:
 
    void input_value()
    {
 
        cout << "Enter an integer\n";
     
        cin >> variable;
     
    }
     
    void output_value()
    {
         
        cout << "Variable entered is ";
            
        cout << variable << "\n";

    }
        
};
 
int main()
{
    
    programming object;
     
    object.input_value();
     
    object.output_value();
     
    return 0;
            
}
 

Calculate Marks

Write a program to calulate sum of marks obtained in 3 subjects. Create a class named student, add a function called input() which accepts 3 numbers, and add another function total() which displays the result.
#include<iostream>
#include<cstdio> 
 
using namespace std;
 
class student
{
    
private:
    
    int m1, m2, m3;
        
public:
    void input()
    {
     
        cout << "Enter marks in m1 = "<< endl;
     
        cin >> m1;
     
        cout << "Enter marks in m2 = "<< endl;
     
        cin >> m2;
            
        cout << "Enter marks in m3 = "<< endl;
            
        cin >> m3;
            
    }
 
    int total()
    {
     
        int sum = this-> m1 + this-> m2 + this-> m3;
 
        cout << "Total is =" <<sum;
 
    }
 
 
}; 
 
int main()
{
    
    student marks;
    
    marks.input();
 
    marks.total();
 
    return 0;
            
}
 
 
 

Mathematical Calculations

Write a program to calculate the sum, product, division of two numbers. Create a class math and create a function for each of these operations. Call these functions in main using switch.
#include<iostream>
#include<cstdio>
 
using namespace std;
 
class math
{

private:
     
    float temp1, temp2;
 
public:
     
    void add()
 {
     
        cout << "enter the value of temp1 " << endl;
                 
        cin >> temp1;
                 
        cout << "enter the value of temp2 " << endl; 
                 
        cin >> temp2;
                 
        cout << "addition is:" << ( temp1 + temp2 ) <<endl;
 
 } 
             
 void sub()
 {
     
        cout << "enter the value of temp1 " << endl;
                
        cin >> temp1;
                
        cout << "enter the value of temp2 " << endl; 
                
        cin >> temp2;
                
        cout << "subtraction is:" << ( temp1 - temp2 ) <<endl;
 
 }
 
 void mul()
 {
        cout << "enter the value of temp1 " << endl;
                
        cin >> temp1;
                
        cout << "enter the value of temp2 " << endl; 
                
        cin >> temp2;
                
        cout << "multiplication is:" << ( temp1 * temp2 ) <<endl;
 
 }
 void div()
 {
        // div by zero not handled by this code
        // for simplicity
     
        cout << "enter the value of temp1 " << endl;
 
        cin>> temp1;
 
        cout << "enter the value of temp2 " << endl; 
                
        cin >> temp2;
                
        cout << "division is:" << ( temp1 / temp2 ) <<endl;
 
 }
};
 
int main()
{
 
    int a;
 
    math obj1;
 
    cout << "enter 1 for add,2 for sub, 3 for mul, 4 for div: "<< endl;
 
    cin >> a;
 
    switch(a)
    {
        case 1: 
        {
            obj1.add();
                
            break;
        }
                
        case 2: 
        {
             
            obj1.sub();
                
            break;
        }
            
        case 3:
        {
                    
            obj1.mul();
                
            break; 
            
        }
            
        case 4:
        {
                    
            obj1.div();
                
            break;
                
        }
            
        default:
        {
            
            cout << "invalid operation";
                
            break;
        }
    }
            
    return 0;
 
}

Odd numbers

Write a progam to find odd number less than 100. Create a class Max. In this class create a function which gives odd numbers
#include<iostream>
#include<cstdio>
 
using namespace std;
 
class Max
{
 
public:
 
    void oddNum()
    {
    
        int i = 1; 
    
        while( i < 100 )
        {
        
            int a = i % 2;
    
            if( 0 != a )
            { 
    
                cout << i << endl;
    
            }
    
            i++;
    
        }
 
    }
 
};
 
int main()
{
 
        Max obj;
        
        obj.oddNum();
 
        return 0; 
}

Multiple object creation

Write a class CRectangle, create function which prints the area of a rectangle. Create two objects for this class with values (3,4) and (5,6).
#include<iostream>
#include<cstdio>
 
using namespace std;
 
class CRectangle
{
    
private:
    
 int x, y;
 
public:
         
    void set_values (int a, int b) 
    {    
        this ->    x = a;
    
        this ->    y = b;
    }
         
    float area ()
    {
        
         return this-> x * this-> y;
     
    }
 
};
 
int main ()
 
{
    CRectangle obj1;
    
    CRectangle obj2;
    
    obj1.set_values (3,4);
    
    obj2.set_values (5,6);
    
    cout << "obj1 area: " << obj1.area() << endl;
    
    cout << "obj2 area: " << obj2.area() << endl;
    
    return 0;
    
} 

Calculate volume

Write a program to calculate the volume of a cuboidal box. Create a class Volume. In this class create a function vol() which prints the volume of a box. Get length, breadth, height of box from the user.
#include<iostream>
#include<cstdio>
 
using namespace std;
 
class Volume
{
    
private:
    
 int x, y, z;
 
public:
         
    void set_values (int a, int b, int c) 
    {    

        this ->    x = a;
    
        this ->    y = b;
        
        this ->    z = c;
        
    }
         
     void vol()
    {
        
        cout << "Volume is :" << this -> x * this-> y * this -> z ;
     
    }
 
};
 
int main ()
 
{
    int a, b, c;
     
    Volume obj;
    
    cout << "Enter length " ;
    
    cin >> a ;
    
    cout << "Enter breadth " ;
    
    cin >> b ;
    
    cout << "Enter height " ;
    
    cin >> c ;
    
    obj.set_values (a, b, c);
    
    obj.vol();
        
    return 0;
    
} 

Print table

Write a program which prints a table. Create a class student. In this class create a function called table() which displays the table of arguemnt passed in main, call this function two times with values 5 and 6 respectively.
#include<iostream>
#include<cstdio>
 
using namespace std;
 
class student
{
    
private:
     
    int t1;
 
public:
    void init( int x ) 
    {
    
         this->t1 = x;
    
    }
        
    void table()
    {
            
        for( int i = 1; i <= 10; i++ )
        {
            
            cout << t1 << " * " << i ;
            cout << " = " << i * t1 << endl;
                     
        }
                            
    }
 
};
 
int main()
{
    
    student tbl;
     
    tbl.init(5);
    
    tbl.table();
    
    cout << "----------" << endl;
    
    tbl.init(6);
    
    tbl.table();
     
    return 0; 
 
}
 

Calculate circumference

Write a program to calculate the circumference of a circle. Create a class student, and, in this class create a function called circle() which displays the cirumference of the circle , get radius from the user.
#include<iostream>
#include<cstdio>
 
using namespace std;
 
class student
{
    
private:
 
    float p1;
 
public:
    void init( float r ) 
    {
    
         this -> p1 = r;
    
    }
        
    void circle()
    {
            
        cout << "Circumference is = " ;
        cout << 2 * 3.14f * p1 <<endl;

    }
 
};
 
int main()
{
    
    float radi;
    
    student pr;
     
    cout << "Enter radius = ";
 
    cin >> radi;
    
    pr.init(radi);
    
    pr.circle();
 
    return 0; 
 
}
 

Classroom Training

Classroom training in C/C++ is available at our training institute. Click here for details. You can also register yourself here.

Video Tutorial

We have created a video tutorial that can be downloaded and watched offline on your windows based computer. It is in the form of an exe file. No installation is required, it runs by double clicking the file. Since the exe file is hosted on the Google Drive, it should be very safe because Google itself checks for any virus or malware. The video can be watched offline, no internet is required.

Pricing

This single video will cost you USD $5. When you download the video, you will be able to watch the first few minutes for free, as a sample. The video app will prompt you for payment through PayPal and other payment options. If you want ALL VIDEOS, NOT JUST THIS ONE then go here: Complete Set of C/C++ Video Tutorials The entire set is priced at USD $50.

Screenshots

This is a screenshot of the software that should give you a good idea of the available functionality. Click on the image to see a larger view. screenshot of the video being played in the software

Installation

This software doesn't require any installation. Just download and double-click to run it. It doesn't require administrative priviliges to run. It runs in limited access mode, so should be very safe.

supports windows xp and later Supported Operating Systems

These videos can be run on 32-bit as well as 64-bit versions of the Microsoft Windows Operating Systems. Windows XP and all later OS are supported. If you want to run it on Windows XP and Windows Vista, then you must also have the .NET Framework Version 3.5 installed on your machines. Those users who have Windows 7 and later donot have to worry because these operating systems already have the .NET Framework installed on them.

Download Links

IMPORTANT NOTE: This download contains ONLY ONE video. The video is about the topic of this tutorial.

Want ALL Videos? If you want ALL VIDEOS, NOT JUST THIS ONE then go here: Complete Set of C/C++ Video Tutorials. TIP: If you plan to buy these videos, then it would be more economical to buy the entire set.

DISCLAIMER: Even though every care has been taken in making this software bug-free, but still please take a proper backup of your PC data before you use it. We shall not be responsible for any damages or consequential damages arising out of the use of this software. Please use it solely at your own risk.

Please download the software here.
download the video Structs in C and C++



Creative Commons License
This Blog Post/Article "Structs in C and C++" by Parveen (Hoven) is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Updated on 2020-02-07. Published on: 2015-10-05