Things we will study ↓
int main()
{
int A[5]; // declaration
int B[5] = {2, 4, 6, 8, 10}; // declaration + initialization
}
// accessing array elements
for(i = 0; i < 5; i++)
{
printf("%d", B[i]);
}
#include <iostream>
using namespace std;
int main()
{
int A[10] = {2, 4, 6, 8, 10};
cout << sizeof(A) << endl; // 20
cout << A[1] << endl; // 4
cout << A[9] << endl; // 0 will be stored if there is no value initialized
// displaying elements of array
for (int i = 0; i < 10; i++)
{
cout << A[i] << endl;
}
// we can also use for each loop to access all the element of an array
for (int x : A)
{
cout << x << endl;
}
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int n;
cout << "Enter Size : ";
cin >> n;
// int A[n]={1,2,3,4,5}; we can use 'n' but cannot initialize value like this
int A[n];
A[0] = 2; // we can do like this or using loop and taking input by the keyboard.
for (int x : A)
{
cout << x << endl;
}
// remember 'variable size' array cannot be initialized.
return 0;
}
Declaration example ↓
struct Rectangle {
int length; // this will take 2 bytes
int breadth; // this will also take 2 bytes
};
// total 4 bytes will be taken when a variable is created
Declaring variable of Reactangle structure ↓
int main()
{
struct Rectangle r; // r will occupy 4 byte memory.
}
Declaration + initialization ↓
int main()
{
struct Rectangle r = {10, 5};
}
Accessing the members of the structure ↓
int main()
{
struct Rectangle r = {10, 5};
r.length = 15;
r.breadth = 10;
}
// dot (.) operator is used for accessing the member
printf("Area of Reactangle is %d", r.length*r.breadth);
Examples of structure ↓
struct Complex
{
int real;
int img;
};
struct Student
{
int roll; // 2 bytes
char name[35]; // 25 bytes
char dept[10]; // 10 bytes
char address[50]; // 50 bytes
};
// total 87 bytes
struct Student s;
s.roll = 10;
s.name = "John";
struct Card
{
int face;
int shape;
int color;
};
int main()
{
struct Card c;
c.face = 1;
c.shape = 0;
c.color = 0;
// directly initializing value
// struct Card c = {1, 0, 0};
}
Now to create 52 cards we can use array.
int main()
{
struct Card deck[52]; // this will create array of structure.
// each card we can access it with the help of index.
// initializing array of structure
// struct Card deck[52] = {{1, 0, 0}, {2, 0, 0},...}
// accessing
printf("%d", deck[0].face);
printf("%d", deck[0].shape);
}
#include <iostream>
using namespace std;
struct Rectangle
{
int length;
int breadth;
char x;
} r5; // we can declare it like this also.
int main()
{
struct Rectangle r1 = {10, 5};
cout<<sizeof(r1); // 12
// accessing member
cout<<r1.length<<endl;
cout<<r1.breadth<<endl;
// changing value
r1.length = 15;
r1.breadth = 7;
return 0;
}
// in structure padding of memory is done
// means some variable will take extra memory
// here char is taking 4 byte same as int.
Example ↓
int main()
{
int a = 10; // data variable
int *p; // pointer declaration
P = &a; // pointer assignment / initialization
printf("%d", a); // 10
printf("%d", *p); // 10 - dereferencing
}
Accessing Heap memory through pointer
#include<stdio.h>
int main()
{
int *p;
p = new int[5]; // C++ programming language
// p = (int *) malloc(5 * sizeof(int)) - C programming language
}
Practise
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int *p;
p = &a;
cout << "Using pointer " << *p; // 10
cout << "address of a " << p; // 0x7ff7ba4d4548
cout << "address of a " << &a; // 0x7ff7ba4d4548
return 0;
}
Pointer to an array
#include <iostream>
using namespace std;
int main()
{
int A[5] = {2, 4, 6, 8, 10};
int *p;
p = A;
// here there is not & because A itself is a starting address of array
// p = &A[0]; we can do this also
// accessing all the array elements using pointer
for (int i = 0; i < 5; i++)
{
cout << p[i] << endl;
}
return 0;
}
Creating an array in heap
#include <iostream>
#include <stdlib.h> // for using malloc
using namespace std;
int main()
{
int *p;
// p = (int *)malloc(5 * sizeof(int));
p = new int[5]; // c++ syntax
p[0] = 10; p[1] = 15; p[2] = 14; p[3] = 21; p[4] = 31;
for (int i = 0; i < 5; i++)
{
cout << p[i] << endl;
}
// after using the dynamic memory we should release it
delete [] p; // as this is an array that's why we are using this syntax
// delete x;
// free(p); this syntax is for C
return 0;
}
#include <iostream>
using namespace std;
struct Rectangle
{
int length;
int breadth;
};
int main()
{
int *p1;
char *p2;
float *p3;
double *p4;
struct Reactange *p5;
cout << sizeof(p1)<< endl; // 8
cout << sizeof(p2)<< endl; // 8
cout << sizeof(p3)<< endl; // 8
cout << sizeof(p4)<< endl; // 8
cout << sizeof(p5)<< endl; // 8
// every pointer takes same amount of memory
return 0;
}
Example:
int main()
{
int a = 10;
int &r = a; // syntax reference
cout<< a;
r++;
cout<< r; // 11
cout<< a; // 11
}
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int &r = a;
// at the time of declaring the reference variable we have to initialize it also.
// later we cannot assign new value to reference we can only change the value.
// updating value of a
a = 15;
cout<< a << r; // 15 15
// updating value of r
r = 25;
cout<< a<< r; // 25 25
// conceptually reference doesn't consume memory it uses same memory of stored variable
int b = 30;
r = b;
cout << a<< r; // 30 30
}
struct Rectangle
{
int length; // size 2 bytes
int breadth; // size 2 bytes
};
int main ()
{
struct Rectangle r = {10, 5};
struct Rectangle *P = &r;
// Pointer always take 2 bytes no matter what is stored in it.
// accessing data
// *P.length = 20; this is wrong as the higher precedence is for (.) operator
// (*P).length = 20; this syntax is complex
// use this ↓
P->length = 20; // this is simple syntax to access the members
}
Creating structure variable dynamically using pointer.
struct Rectangle
{
int length;
int breadth;
};
int main()
{
struct Rectangle *P;
P = (struct Rectangle *)malloc(sizeof(struct Rectangle));
P->length = 10;
P->breadth = 5;
}
#include <stdio.h>
struct Rectangle
{
int length;
int breadth;
};
int main()
{
// Rectangle r = {10, 5}; // we are not using 'struct' keyword and it still works
// this only works with C++ compiler
struct Rectangle r = {10, 5};
Rectangle *p = &r;
// now to access member using pointer variable we cannot use dot (.) operator.
cout << p->length << endl;
cout << p->breadth << endl;
// for normal variable use dot operator and for pointer variable use arrow operator.
return 0;
}
#include <stdio.h>
struct Rectangle
{
int length;
int breadth;
};
int main()
{
// now we will see how to create object of Rectangle in heap.
struct Rectangle *p; // this will be created in stack.
p = (struct Rectangle *)malloc(sizeof(struct Rectangle));
// now using above code a pointer will be created in heap and 'p' will be pointing to it.
p->length = 15;
p->breadth = 7;
cout << p->length << endl;
cout << p->breadth << endl;
return 0;
}
#include <iostream>
using namespace std;
struct Rectangle
{
int length;
int breadth;
};
int main()
{
Rectangle *p;
p = new Rectangle;
p->length = 15;
p->breadth = 7;
cout << p->length << endl;
cout << p->breadth << endl;
return 0;
}
Some terminology ↓
#include <iostream>
using namespace std;
int add(int a, int b)
{
int c = 0;
c = a + b;
return c;
}
int main()
{
int num1 = 10, num2 = 15, sum;
sum = add(num1, num2);
cout << "Sum is " << sum;
return 0;
}
void swap(int x, int y)
{
int temp;
temp = x;
x = y;
y = temp;
}
int main()
{
int a, b;
a = 10;
b = 20;
swap(a, b);
printf("%d %d", a, b);
}
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
int main()
{
int a, b;
a = 10;
b = 20;
swap(&a, &b);
printf("%d %d", a, b);
}
void swap(int &x, int &y)
{
int temp;
temp = x;
x = y;
y = temp;
}
int main()
{
int a, b;
a = 10;
b = 20;
swap(a, b);
printf("%d %d", a, b);
}
#include <iostream>
using namespace std;
int increment(int a)
{
a++;
cout << a; // 2
}
int main()
{
int num1 = 1;
increment(num1);
cout << num1; // 1
}
// This above code proves that there is no change occurs on actual parameters when we use call by value mechanism.
#include <iostream>
using namespace std;
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
/* we doesn't have to return anything because the result of this
function is directly reflecting to the actual parameter */
int main()
{
int num1 = 10, num2 = 15;
swap(&num1, &num2);
cout << "First Number" << num1 << endl; // 15
cout << "Second Number" << num2 << endl; // 10
}
#include <iostream>
using namespace std;
void swap(int &x, int &y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
/*
There are two possibilities that compilier can convert above function
to inline function or it can make the parameters as pointers also.
*/
int main()
{
int num1 = 10, num2 = 15;
swap(num1, num2);
cout << "First Number" << num1 << endl; // 15
cout << "Second Number" << num2 << endl; // 10
}
void func(int A[], int n)
{
int i;
for(i = 0; i < n; i++)
{
printf("%d", A[i]);
}
}
int main()
{
int A[5] = {2, 4, 6, 8, 10};
fun(A, 5);
}
int * fun(int n)
{
itn *P;
P = (int *)malloc(n * sizeof(int));
return (P);
}
int main()
{
int *A;
A = fun(5);
...
...
}
#include <iostream>
using namespace std;
// remember array cannot be passed as value they are always passed by address
void fun(int A[])
{
cout << sizeof(A) / sizeof(int) << endl;
// this gives 2 as output because A here is a pointer to array and its size is 8, 8/4 = 2
}
int main()
{
int A[] = {2, 4, 6, 8, 10};
int n = 5;
fun(A);
cout << sizeof(A) / sizeof(int) << endl; // while this gives 5 as output.
for (int x : A)
cout << x << " ";
return 0;
}
#include <iostream>
using namespace std;
void fun(int A[], int n)
{
// for(int x : A)
// cout << x << " ";
// We cannot use for each loop in a function because A is a pointer not an Array
// Another reason would be that for each loop only work for the array which is declared in the same scope.
// but we can use for loop
for (int i = 0; i < n; i++)
{
cout << A[i] << " ";
}
}
int main()
{
int A[] = {2, 4, 6, 8, 10};
int n = 5;
fun(A, n);
for (int x : A)
cout << x << " ";
return 0;
}
#include <iostream>
using namespace std;
void fun(int *A, int n) // ***
{
for (int i = 0; i < n; i++)
{
cout << A[i] << " ";
}
}
int main()
{
int A[] = {2, 4, 6, 8, 10};
int n = 5;
fun(A, n);
for (int x : A)
cout << x << " ";
return 0;
}
#include <iostream>
using namespace std;
void fun(int *A, int n)
{
A[0] = 15;
}
int main()
{
int A[] = {2, 4, 6, 8, 10};
int n = 5;
fun(A, n);
for (int x : A)
cout << x << " ";
return 0;
}
#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] << " ";
}
/*
array is created in heap inside "fun" function and even "main" function can access it.
*/
return 0;
}
struct rectangle
{
int length, breadth;
};
int area(struct rectangle r1)
{
return (r1.length * r1.breadth);
}
int main()
{
struct rectangle r = { 10, 5};
printf("%d", area(r));
// we could send length and breadth separately but instead we are passing the structure.
// Benefit of structure is that we can pass multiple parameter inside a structure.
}
int area(struct rectangle &r1)
{
return (r1.length * r1.breadth);
}
int main()
{
struct rectangle r = { 10, 5};
printf("%d", area(r));
}
void changeLength(struct rectangle *p, int l)
{
p -> length = l;
}
int main()
{
struct rectangle r = { 10, 5};
changeLength(&r, 20);
}
struct text
{
int A[5];
int n;
};
void fun(struct test t1)
{
// for this function every thing will be copied even array.
t1.A[0] = 10;
t1.A[1] = 9;
// this won't change the actual array in main function as the structure is passed as call by value
}
int main()
{
struct test t = {{2,4,6,8,10}, 5};
fun(t);
}
#inlcude <iostream>
using namespace std;
struct Rectangle
{
int length, breadth;
};
void fun(struct Rectangle r)
{
r.length = 20; // this won't affect the actual parameter.
cout << "Length " << r.length << endl << "Breadth " << r.breadth << endl;
}
int main()
{
struct Rectangle r = {10, 5};
fun(r);
cout << "Length " << r.length << endl << "Breadth " << r.breadth << endl;
return 0;
}
#inlcude <iostream>
using namespace std;
struct Rectangle
{
int length, breadth;
};
void fun(struct Rectangle *p)
{
p->length = 20; // this will affect the actual parameter.
cout << "Length " << p->length << endl << "Breadth " << p->breadth << endl;
}
int main()
{
struct Rectangle r = {10, 5};
fun(&r);
cout << "Length " << r.length << endl << "Breadth " << r.breadth << endl;
return 0;
}
#include <iostream>
using namespace std;
struct Rectangle
{
int length, breadth;
};
struct Rectangle *fun()
{
struct Rectangle *p;
p = new Rectangle;
p->length = 15;
p->breadth = 7;
return p;
}
int main()
{
struct Rectangle *ptr = fun();
cout << "Length " << ptr->length << endl << "Breadth " << ptr->breadth << endl;
return 0;
}
Now we will use constructor in C++ program. ↓
#include <stdio.h>
int main()
{
int length = 0, breadth = 0; // its a good practise to initialize a variable when we are declaring it.
printf("Enter length and breadth : ");
scanf("%d%d", &length, &breadth);
int area = length * breadth;
int peri = 2 * (length + breadth);
printf("Area = %d \n Perimeter = %d\n", area, peri);
return 0;
}
#include <stdio.h>
int area(int length, int breadth)
{
return length * breadth;
}
int peri(int length, int breadth)
{
return 2 * (length + breadth);
}
int main()
{
int length = 0, breadth = 0;
printf("Enter length and breadth : ");
scanf("%d%d", &length, &breadth);
int a = area(length, breadth);
int p = peri(length, breadth);
printf("Area = %d \n Perimeter = %d\n", a, p);
return 0;
}
#include <stdio.h>
struct Rectangle
{
int length, 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;
}
int peri(struct Rectangle r)
{
return 2 * (r.length + r.breadth);
}
int main()
{
struct Rectangle r = {0, 0};
int l, b;
printf("Enter length and breadth : ");
scanf("%d%d", &l, &b);
initialize(&r, l, b);
int a = area(r);
int p = peri(r);
printf("Area = %d \n Perimeter = %d\n", a, p);
return 0;
}
#include <iostream>
struct Rectangle
{
int length, breadth;
void initialize(int l, int b)
{
length = l;
breadth = b;
}
int area()
{
return length * breadth;
}
int peri()
{
return 2 * (length + breadth);
}
};
int main()
{
struct Rectangle r = {0, 0};
int l, b;
printf("Enter length and breadth : ");
scanf("%d%d", &l, &b);
r.initialize(l, b);
int a = r.area();
int p = r.peri();
printf("Area = %d \n Perimeter = %d\n", a, p);
return 0;
}
#include <iostream>
class Rectangle
{
public: // making it public because it is private by default.
int length, breadth;
void initialize(int l, int b)
{
length = l;
breadth = b;
}
int area()
{
return length * breadth;
}
int peri()
{
return 2 * (length + breadth);
}
};
int main()
{
struct Rectangle r; // direct initialization we can't do with class.
int l, b;
printf("Enter length and breadth : ");
scanf("%d%d", &l, &b);
r.initialize(l, b);
int a = r.area();
int p = r.peri();
printf("Area = %d \n Perimeter = %d\n", a, p);
return 0;
}
#include <iostream>
using namespace std;
class Rectangle
{
private:
int length, breadth;
public:
Rectangle() // default constructor
{
length = breadth = 1;
}
Rectangle(int l, int b); // parameterized constructor
int area();
int peri();
int getLength()
{
return length;
}
void setLength(int l)
{
length = l;
}
~Rectangle(); // destructor
};
Rectangle ::Rectangle(int l, int b)
{
length = l;
breadth = b;
}
int Rectangle ::area()
{
return length * breadth;
}
int Rectangle ::peri()
{
return 2 * (length + breadth);
}
Rectangle ::~Rectangle() // destructor is called when the object is going out of the scope
{
cout << "Destructor";
}
int main()
{
Rectangle r(10, 5);
cout << r.area() << endl;
cout << r.peri() << endl;
r.setLength(20);
cout << r.getLength() << endl;
int l, b;
return 0;
}
Why generic classes? Let's understand using a example class ↓
class Arithmetic
{
private:
int a;
int b;
public:
Arithmetic(int a, int b);
int add();
int sub();
};
Arithmetic ::Arithmetic(int a, int b)
{
// as the member name and function arguments name are same
// "this" is pointer to current object.
this->a = a; // this->a is member "a"
this->b = b;
}
int Arithmetic :: add()
{
int c;
c = a + b;
return c;
}
int Arithmetic :: sub()
{
int c;
c = a - b;
return c;
}
template <class T>
class Arithmetic
{
private:
T a;
T b;
public:
Arithmetic(T a, T b);
T add();
T sub();
}; // effect of template ends here.
// again we have to use template for function
// because this constructor belongs to a class which is a template
template <class T>
Arithmetic<T> ::Arithmetic(T a, T b)
{
this->a = a;
this->b = b;
}
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);
// now everywhere there is a "T" it will be replaced by "int" and this class becomes pure integer class.
cout << ar.add();
Arithmetic<float> ar1(1.5, 1.2);
cout << ar1.add();
}