Structures

Examples:

1.

#include <iostream>
using namespace std;

    struct Rectangle
    {
        int length;
        int breadth;
    };

int main() {
    
    struct Rectangle r1; // or just Rectangle r1
    r1.length=15;
    r1.breadth=10; 

    // or

    struct Rectangle r2{16, 5};

    cout << "Area of rectangle r1 = " << r1.length*r1.breadth << endl;
    cout << "Area of rectangle r2 = " << r2.length*r2.breadth;

    return 0;
}

Another way of making structs :
Pasted image 20231206000034.png

2.

#include <iostream>
using namespace std;

    struct Student
    {
        int rollNo;
        char *name;
    };

int main() {
    
    Student s1;
    s1.rollNo = 23;
    s1.name = "autumn lol";

    cout << "Name and rollNo are: " << s1.name << s1.rollNo;

    return 0;
}

3. struct as an array

#include <iostream>
using namespace std;

    struct Student {
        char *name;
        int rollNo;
    };

int main() {
    
    Student deck2[3] = {{"hitarth", 40}, {"dev", 12}, {"aryan", 51}};

    cout << deck2[0].name << endl;
    cout << deck2[1].name << endl;
    cout << deck2[2].rollNo << endl;

    return 0;
}
  • Output :
    Pasted image 20231205234621.png

Size of Struct :

Pasted image 20231206000553.png
Pasted image 20231206002136.png

  • Here the char x; has a size of 4 bytes instead of 1 byte because we are using it inside of of struct so padding of memory is done here as it is easy for the processor / machine tor read the structure. Later on it'll discard the last three bytes.
  • More about sizeof structs here : https://www.learncpp.com/cpp-tutorial/struct-miscellany/

Pointers :

• Pointer is a address variable that is meant for storing address of not data
itself
• They are used for indirect access of data
• For a program to use heap memory , pointers is used
• To access heap memory and resources outside the main memory like
internet, keyboard , monitor etc pointers is used
• Pointers are also used for parameter passing

  • Dereferencing a pointer is basically accessing the value at the address stored in the pointer.
  • Remember that whenever you declare a variable it will be stored in the stack memory.
    • Pasted image 20231206184112.png

Accessing the heap memory :

  • We use malloc(size in bytes) to access the heap memory.
    Pasted image 20231206184449.png
  • Here malloc returns a void pointer so we have to typecast it as a int pointer.
    • Now this p pointer will get the address 5000.

malloc is generally used in C lang only (it can be used in c++ too tho) and for c++ we use :
Pasted image 20231206184925.png

Syntax :
Pasted image 20231206185235.png

#include<iostream>
#include <stdlib.h>
using namespace std;
int main()
{

    int *p;
    p = new int[3]; // to access heap memory
    p[0]=10; p[1]=15; p[2]= 14;

    for (int i = 0; i < 3; i++)
    {
        cout << p[i] << endl;
    }
    

 return 0;
}
  • Output :
    Pasted image 20231206190510.png

Remember : Whenever you are dynamically allocating the memory u have to release the memory when u are done using it.

  • delete [ ] p : to delete int *p
  • delete variable_name : to free the memory used by a variable pointer.

size of the pointer is independent of it's data type :

Pasted image 20231206191006.png

Pointer to a structure:

Pasted image 20231206193456.png

  • Here we wrote (*p).length = 20; with *p enclosed in bracket as . has higher precedence than *.
  • Pasted image 20231206193643.png
    • To make things simple c++ me ham arrow (->) ka use karte hai.

Example :
Pasted image 20231206194330.png

For heap memory :
Pasted image 20231206193924.png

Reference : (only available in C++)

It is a nickname / alias given to a variable.

  • int &r : means r is a reference
    Pasted image 20231206191702.png
  • Here we can call the a variable with the r name / alias.

Pasted image 20231206192253.png

  • here both a and r will print the value of 30.

Functions :

Parameter Passing Methods

  • Pass by value
  • Call by address
  • Call by reference (not advised to be used) : Remember ki isme function ka code main() function ke andar copy paste ho jayega so ye original values ko change kar deta hai

Array

Pass by address:

#include <iostream>
using namespace std;

void fun (int arr2[], int n) {  //we can use `int *arr2` instead of of `int arr2[]` as well. 
    for (int i = 0; i < n; i++)
    {
        cout << arr2[i] <<" ";
    }
    
}

int main()
{

    int arr[] = {1, 2, 3, 4, 5};
    fun(arr, sizeof(arr)/sizeof(arr[0]));

    return 0;
}
#include <iostream>
using namespace std;

void fun (int *arr2, int n) {
    arr2[2]=20;
}

int main()
{

    int arr[] = {1, 2, 3, 4, 5};
    cout << arr[2] << endl;          // will print 3
    fun(arr, sizeof(arr)/sizeof(arr[0]));
    cout << arr[2] << endl;          // will print 20

    return 0;
}

program to create an array inside a pointer function :

#include<iostream>
using namespace std;

int * fun(int size)
{
    int *p;
    p = new int[size];

    for (int i = 0; i < size; i++)
    p[i]=i+1;
    return p;
    
}

int main()
{
    int *ptr, sz=5;
    ptr = fun(sz);

    for(int i=0; i<sz; i++)
    cout<<ptr[i]<<endl;

    return 0;
}

Structure as a parameter :

Call by value:

#include<iostream>
using namespace std;

struct Rectangle
{
    int length;
    int breadth;
};

int area (struct Rectangle r1)
{
    r1.length++;
    return (r1.length*r1.breadth);
}

int main()
{
    Rectangle r = {10,5};
    cout << area(r);

    return 0;
}
  • Output will be 55.

Call by reference :

#include<iostream>
using namespace std;

struct Rectangle
{
    int length;
    int breadth;
};

void incr (struct Rectangle &r1)
{
    r1.length++;
}

int main()
{
    Rectangle r = {10,5};
    incr(r);
    cout << r.length;

    return 0;
}
  • Output will be 11.

Call by address

#include<iostream>
using namespace std;

struct Rectangle
{
    int length;
    int breadth;
};

void incr(struct Rectangle *r1)
{
    r1->length = 20;
}

int main()
{
    Rectangle r = {10, 5};
    incr(&r);
    cout << r.length;
    return 0;
}
  • Output : 20

Point to note :

Pasted image 20231206232459.png

  • Here we have an array inside of a struct. We know that array can only be passed by address so what if we passed the entire structure which contains the array by call by value.
    Answer is simple, since the entire structure is being copied so will be the array, i.e. array will simply be copied, any changes to this copied array will not be reflected in the original array.

Struct pointer, creating a struct in heap, function pointer :

#include<iostream>
using namespace std;
    
struct Rectangle
{
    int length;
    int breadth;
};

struct Rectangle *fun()
{
    struct Rectangle *p;
    p = new Rectangle; //heap pe hamne ek struct banaya

    p->length = 15; // is equivalent to `(*p).length = 15;`
    p->breadth = 7;
    
    return p; // p ka address return ho jayega
};


int main()
{

     struct Rectangle *ptr=fun();
     cout << (*ptr).length << endl;
     cout << ptr->length << endl;

    return 0;
}

Ultimate Struct Code : (must read) :

#include<iostream>
using namespace std;

struct Rectangle
{
    int length;
    int breadth;
};

void initialize (struct Rectangle *r, int l, int b)
{
    r->length=l;
    r->breadth=b;
}

int area (struct Rectangle r)
{
    return r.length*r.breadth;
}

void changeLength (struct Rectangle *r, int l)
{
    r->length=l;
}

int main()
{

    struct Rectangle r;

    initialize(&r, 10, 5);
    area(r);
    changeLength(&r, 20);

    return 0;
}

Classes and Constructors :

Example 1 :

#include<iostream>
using namespace std;

class Rectangle {
private:
    int length;
    int breadth;
public:
    void initialize (int l, int b)
    {
        length = l;
        breadth = b;
    }

    int area()
    {
        return length*breadth;
    }
    
    void changeLength(int l)
    {
        length = l;
    }
};

int main()
{

    Rectangle r;

    r.initialize(10,5);
    r.area();
    r.changeLength(20);

    return 0;
}

Example 2:

Suppose baad me initialize karne ke bajaye hame declare and initialize karna hai to we'll rename the function initialize to the class name i.e. Rectangle and remove the function return type as well.
For e.g. :

#include<iostream>
using namespace std;

class Rectangle {
private:
    int length;
    int breadth;
public:
    Rectangle (int l, int b)
    {
        length = l;
        breadth = b;
    }

    int area()
    {
        return length*breadth;
    }
    
    void changeLength(int l)
    {
        length = l;
    }
};

int main()
{

    Rectangle r(10,5);

    // r.initialize(10,5);
    r.area();
    r.changeLength(20);

    return 0;
}
  • Now this Rectangle function is called constructor instead of a function as we are giving the same name as class name.

Example 3: Functions inside a struct :

#include <iostream>
using namespace std;

struct Rectangle
{
    int length;
    int breadth;
    // notice that the function below is accessing the `length` variable outside the function
    void initialise(int l, int b)
    {
        length = l;
        breadth = b;
    }

    int area()
    {
        return length * breadth;
    }

    int perimeter()
    {
        return 2 * (length + breadth);
    }

};

int main()
{
    Rectangle r;
    r.initialise(10, 5);
    cout << "area is: " << r.area() << endl;
    cout << "perimeter is: " << r.perimeter() << endl;
    

    return 0;
}

Converting the above program to a class based program :

#include <iostream>
using namespace std;

class Rectangle
{
private:
    int length;
    int breadth;
public:
    Rectangle(int l, int b)
    {
        length = l;
        breadth = b;
    }

    int area()
    {
        return length * breadth;
    }

    int perimeter()
    {
        return 2 * (length + breadth);
    }

};

int main()
{
    Rectangle r(10, 5);
    cout << "area is: " << r.area() << endl;
    cout << "perimeter is: " << r.perimeter() << endl;
    

    return 0;
}

NOTE : Struct and Class are same, the only difference is that in Struct everything is public and in Class everything is private by default.

Template Class:

Before :
Pasted image 20231208231623.png
After :
Pasted image 20231208231639.png

#include <iostream>
using namespace std;

template <class T>
class Arithmetic
{
    private:
        T a;
        T b;
    public:

    // constructor function
    Arithmetic(T a, T b);
    
    T add();
    T sub();
};

template <class T>
Arithmetic<T>::Arithmetic(T aTemp, T bTemp)
{
    this-> a = aTemp;
    this-> b = bTemp;
}

template <class T>
T Arithmetic<T>::add()
{
    T c;
    c=a+b;
    return c;
}

template <class T>
T Arithmetic<T>::sub()
{
    T c;
    c=a-b;
    return c;
}


int main()
{
    Arithmetic<int> ar(10, 5);
    cout<<ar.add()<<endl;
    Arithmetic<float> ar1(1.5, 1.2);
    cout << ar1.add()<<endl;

    return 0;
}
  • Pasted image 20231209002154.png
  • Pasted image 20231209002205.png
  • this->a = aTemp; and this->b = bTemp;: These lines are assigning the values of the parameters aTemp and bTemp to the data members a and b of the class instance (object) being constructed. The use of this-> is optional in this context, but it makes it clear that you are referring to the class members rather than the parameters.
    • Pasted image 20231209004720.png
    • Notice that here this is a pointer to the current object (notice how the color of a and b are same).

If we want to define the functions outside of the class we do it like this :
Pasted image 20231209005338.png