Explain abstraction.
- Simplified view of an object in user’s language is called abstraction.
- It is the simplest, well-defined interface to an object in OO and C++ that provides all the expected features and services to the user in a safe and predictable manner.
- It provides all the information that the user requires.
- Good domain knowledge is important for effective abstraction.
- It separates specifications from implementation & keeps the code simpler and more stable.
What is a data encapsulation?
Data Encapsulation:- The wrapping up of data and functions into a single unit (Class) is known as Encapsulation.
- By encapsulating the data inside the class; data is not accessible to the outside world. Only those functions which are wrapped inside the class can access it.
- This provides protection to the data since access to it is controlled.
- Objects of the class can thus access the data only using the methods provided by the class.
Class MyClass
{
int roll, marks;
public:
{
int getmarks()
{
return marks;
}
}
};
int main()
{
MyClass s;
int m;
m = s.getmarks;
}
- As seen above, the class MyClass has two data members viz. roll and marks.
- These members cannot be accessed directly from outside the class i.e. they are encapsulated inside the class.
- To access them, we need to create object of that class and invoke the data accessing function (‘getmarks’ in this case) using that object.
What is Polymorphism?
- Polymorphism: Poly – Multiple and Morph – Form. Polymorphism means the ability to take more than one form.
- An operation may exhibit different behavior in different instances.
- The behavior depends on the types of data used in the operation.
- For example, consider addition operation. For two numbers, the operation will generate sum. In case of two strings, it will generate a third string with concatenation.
- Thus, polymorphism allows objects with different internal structure to share same external interface.
- This means that a general class of operations can be accessed in the same manner even though specific actions associated with each operation may differ.
There are two types of polymorphism:
Compile Time Polymorphism
Achieved using operator overloading and function overloading.
Rum Time Polymorphism
Achieved using virtual functions.
What is Typecasting? Explain with examples.
Typecasting- Converting the value of one type into another type is called as typecasting.
- C++ is very strict about type compatibility.
- Different variable types must be cast when their values are assigned to each other.
- Typecasting enables data type conversion.
- C++ supports implicit conversions and explicit conversion.
- Implicit conversions automatically performed when a value is copied to a compatible type.
- If there is an operation between an int and a float, the int is promoted to float before performing operation.
You can cast types explicitly as follows
int i, j, k;
k = i * float(j);
The variable ‘j’ is converted to float and used to calculate the value of k.
What is const qualifier? Explain with an example.
- The qualifier const can be applied to the declaration of any variable to indicate that its value will not be changed.
- Once a variable is declared with const qualifier, it no longer remains a variable (i.e. its value cannot be changed).
- Variable with const qualifier is often named in uppercase.
- A const must be initialized with some value.
Example:
const TYPE x = 10; //where TYPE is any data type.
const int x = 5; // This will define x as constant with value 5
- Note that once const is defined, its value cannot be changed by arithmetic operations or assignment.
What is an array?
- An array is a collection of variables of the same type that are referred to through a common name.
- A specific array element is accessed by an index.
- In C++ arrays consist of contiguous memory location.
- The lowest memory address corresponds to first element and the highest to the last element of the array.
- Arrays could be single dimensional or multi dimensional.
- A string is most common example of an array. It is a single dimensional array of characters.
The general form for declaring a single dimensional array is:
type var_name[size];
type is data type
var_name is name given to the array variable
size is size of the array;
Example:
int a[10]; // declares an array of 10 integers.
- Array indexing starts from 0. To access nth element of an array (n-1)th index is to be used. i.e. a[3] = 5; will assign value 5 to the 4th element of array.
Explain following storage classes in C++.
Auto:- This is the default storage class.
- Variables in this class are automatically created and initialized when they are defined.
- These variables are then destroyed at the end of the block containing their definition.
- They are not visible outside that block.
Register:- This is a type of auto variable.
- It gives a suggestion to the compiler to use a CPU register for performance.
Static:- The scope of static variable is local to the function which contains its definition.
- It is never destroyed and retains its value between calls to that function.
Extern:- This is a static variable.
- Its definition and placement is determined when all object and library modules are combined (linked) to form the executable code file.
- It can be visible outside the file where it is defined.
Explain Overriding.
- In overriding both the base and derived class have member functions with same name and arguments.
- To imply overriding functionality we need parent and child classes. In the child class you define the same method signature as one defined in the parent class.
- To override a method, a subclass of the class that originally declared the method must declare a method with the same name, return type (or a subclass of that return type), and same parameter list.
- Method overriding must have same: method name, data type, argument list.
Example:
class Base
{
public:
void diplay()
{
cout << "Base class";
}
};
class Derived:public Base
{
public:
void display()
{
cout << "Derived Class";
}
}
int mian()
{
Base b;
Derived d;
b.display();
d.display();
}
What is a concrete derived class?
- The derived class that implements the missing functionality of an abstract class is called concrete derived class.
- A concrete derived class has no virtual functions.
- It provides functions for its inherited pure virtual functions. This is to say, it provides all missing functionalities of the abstract class.
- A concrete derived class is a derived class which implements the all functionality that missed in the super class.
- A derived class is a class that inherits the properties from its super class. For example, a Cat is a super class and Manx cat is a derived class which has all properties of a cat and does not have a tail.
- Inheritance is one of the important features of OOP which allows us to make hierarchical classifications of classes.
- In this, we can create a general class which defines the most common features.
- Other more specific classes can inherit this class to define those features that are unique to them.
- In this case, the classes which inherit from other classes, is referred as derived class.
Example:
A general class vehicle can be inherited by more specific class car and bike. The class car and bike are derived classes in this case.
class vehicle
{
int fuel_cap;
public:
drive();
};
class car : public class vehicle
{
public:
roll_windows();
};
class bike : public class vehicle
{
public:
kick_start();
};
Explain Loops – While loop, Do-while loop, for loop.
While loop- Loops are used to carry out certain instruction(s) in continuation for a fixed no of times.
- If the condition is true, the loop body will be executed.
- The key point of while loop is that the loop will not even run once when the condition false.
- If the condition is false, the loop body will be skipped and the first statement after the while loop will be executed.
Syntax of while loop:
//initialization statement(s)
while (condition)
{
//statement1;
//statement2;
….
….
}
Example:
x = 0; // initialization stmt
while (x < 10)
{
cout << x<<”\n”;
x++;
}
This prints numbers 0 to 9 on the screen.
Do- while loop- This is similar to while loop; the only difference is unlike while loop, in do-while loop condition is checked after the loop statements are executed.
- This means the statements in the do while loop are executed at least once; even if the condition fails for the first time itself.
Syntax of Do-while loop:
//initialization stmt(s)
do
{
Statement1;
Statement2;
}
while (condition)
Example:
x = 0; // initialization stmt
do
{
cout << x << ”\n”;
x++;
}
while (x < 10);
This prints numbers 0 through 9 on the screen.
For loop- It does exactly the same thing as while loop; only difference is the initialization, the condition statement is written on the same line.
- This is used when we want to execute certain statements for a fixed number of times.
- This is achieved by initializing a loop counter to a value and increasing or decreasing the value for certain no of times until a condition is satisfied.
- The loop statements are executed once for every iteration of the for loop.
Syntax of For loop:
for (initialize loop counter; condition checking; increasing/decreasing loop counter)
{
//statement1;
//statement2;
}
Example:
for (x = 0; x < 10; x++)
{
cout << x <<”\n”;
}
This code snippet will print numbers 0 to 9.
What are function prototypes?
- A function prototype is a declaration of a function that omits the function body.
- It specifies the function's name, argument types and return type.
- In C++ all functions must be declared before they are used.
- Prototypes enable complier to provide stronger type checking.
- When prototype is used, the compiler can find and report any illegal type conversions between the type of arguments used to call a function and the type definition of its parameters.
- It can also find the difference between the no of arguments used to call a function and the number of parameters in the function. Thus function prototypes help us trap bugs before they occur.
- In addition, they help verify that your program is working correctly by not allowing functions to be called with mismatched arguments.
A general function prototype looks like following:
return_type func_name(type param_name1, type param_name2, …,type param_nameN);- The type indicates data type. Parameter names are optional in prototype.
Following program illustrates the value of function parameters:
void sqr_it(int *i); //prototype of function sqr_it
int main()
{
int num;
num = 10;
sqr_it(num); //type mismatch
return 0;
}
void sqr_it(int *i)
{
*i = *i * *i;
}
Since sqr_it() has pointer to integer as its parameter, the program throws an error when we pass an integer to it.
What is function overloading?
- Function overloading is the process of using the same name for two or more functions.
- The secret to overloading is that each redefinition of the function must use either different types of parameters or a different number of parameters.
- It is only through these differences that the compiler knows which function to call in any situation.
Consider following program which overloads MyFunction() by using different types of parameters:
#include <iostream>
Using namespace std;
int MyFunction(int i);
double MyFunction(double d);
int main()
{
cout <<MyFunction(10)<<”\n”; //calls MyFunction(int i);
cout <<MyFunction(5.4)<<”\n”; //calls MyFunction(double d);
return 0;
}
int MyFunction(int i)
{
return i * i;
}
double MyFunction(double d)
{
return d * d;
}
Now the following program overloads MyFunction using different no of parameters:
#include <iostream>
Using namespace std;
int MyFunction(int i);
int MyFunction(int i, int j);
int main()
{
cout <<MyFunction(10)<<”\n”; //calls MyFunction(int i);
cout <<MyFunction(1, 2)<<”\n”; //calls MyFunction(int i, int j);
return 0;
}
int MyFunction(int i)
{
return i;
}
double MyFunction(int i, int j)
{
return i * j;
}
Note: The key point about function overloading is that the functions must differ in regard to the types and/or number of parameters. Two functions differing only in their return types cannot be overloaded.
Difference between passed by value and passed by reference.
Passed by Value | Passed by Reference |
---|
Passes an argument by value. | Passes an argument by reference. |
Specifying the ByVal keyword. | Specifying the ByRef keyword. |
The procedure code does not have any access to the underlying element in the calling code. | The procedure code gives a direct reference to the programming element in the calling code. |
In this, you are sending a copy of the data. | In this, you are passing the memory address of the data that is stored. |
Changes do not affect the actual value. | Changes to the value affect the original data. |
Explain operator overloading.
- C++ provides ability to overload most operators so that they perform special operations relative to classes. For example, a class String can overload the + operator to concatenate two strings.
- When an operator is overloaded, none of its original meanings are lost. Instead, the type of objects it can be applied to is expanded. By overloading the operators, we can use objects of classes in expressions in just the same way we use C++’s built-in data types.
- Operators are overloaded by creating operator functions. An operator function defines the operations that the overloaded operator will perform on the objects of the class. An operator function is created using the keyword operator.
Example:
Consider class String having data members char *s, int size, appropriate function members and overloaded binary operator + to concatenate two string objects.
class String
{
char *s;
int sz;
public:
String(int n)
{
size = n;
s = new char [n];
}
void accept()
{
cout <<”\n Enter String:”;
cin.getline(s, sz);
}
void display()
{
cout<<”The string is: ”<<s;
}
String operator +(String s2) // ‘+’ operator overloaded
{
String ts(sz + s2.sz);
for(int i = 0; s[i]!=’\0’;i++)
ts.s[i] = s[i];
for(int j = 0; s2.s[j]!=’\0’; i++, j++)
ts.s[i] = s2.s[j];
ts.s[i] = ‘\0’;
return ts;
}
};
int main()
{
String s1, s2, s3;
s1.accept();
s2.accept();
s3 = s1 + s2; //call to the overloaded ‘+’ operator
s3.display();
}
- If you pass strings “Hello” and “World” for s1 and s2 respectively, it will concatenate both into s3 and display output as “HelloWorld”.
- Operator overloading can also be achieved using friend functions of a class.
Explain static member function?
- Static member functions are used to maintain a single copy of a class member function across various objects of the class.
- Static member functions can be called either by itself, independent of any object, by using class name and :: (scope resolution operator) or in connection with an object.
Restrictions on static member functions are:
1. They can directly refer to other static members of the class.
2. Static member functions do not have this pointer.
3. Static member function cannot be virtual.
Though there are several restrictions on static member functions, one good use of them is to initialize private static data members of a class before any object is created.
Example:
#include <iostream>
using namespace std;
class S
{
static int i;
public:
static void init(int x)
{
i = x;
}
void show()
{
cout << i;
}
};
int S :: i;
int main()
{
S :: init(100); //initialize static variable i before creating object
S x;
x.show();
return 0;
}
What are default arguments in functions?
- C++ allows a function to assign a parameter a default value when no argument corresponding to that parameter is specified in a call to that function.
- The default value is specified in a manner syntactically similar to a variable initialization.
- For example, this declares MyFunction as taking one int argument with a default value of 0.
Void MyFunction(int i = 0)
{
//…
//…
}
Now, this MyFunction() can be called one of the following two ways:
MyFunction(10); //passing explicit value
MyFunction(); //not passing any value; function will give default value
- One of the reasons why default arguments are included in C++ is because they provide another method for the programmer to manager greater complexity.
- To handle the widest variety of situations, quite frequently a function contains more parameters than are required for its most common usage.
- Thus, when the default arguments apply, you need to specify only the arguments that are meaningful to the exact situation, not all those needed by the most general case.
What is a constructor?
- Constructors allow initialization of objects at the time of their creation.
- Constructor function is a special function that is a member of the class and has same name as that of the class.
- An object’s constructor is automatically called whenever the object is created (statically or dynamically).
- Constructors are always public. They are used to make initializations at the time of object creation.
Consider following example of a stack class:
#include <iostream>
using namespace std;
class stack
{
int top, bottom;
int data[20];
stack() //constructor function
{
top = bottom;
cout <<”Inside Stack Constructor: Stack initialized”;
}
int stackfull()
{
return ((top == max – 1)?1:0);
}
int stackempty()
{
return (top == bottom)?1:0);
}
void push(int no)
{
if(stackfull())
cout<<”Stack is full”;
else
data[++top] = no;
}
int pop()
{
if(stackempty())
cout<<”Nothing to pop.. Stack is Empty!”;
else
return(data[top--]);
}
};
int main()
{
int i, no;
stack st; //object is created; hence constructor is invoked- stack initialization done
cout <<” Entered Main\n”;
for(i = 0; i < 10; i++)
st.push(i);
no = s.pop();
cout <<”The popped element is:”<<no;
return 0;
}
The output of the program would be:
Entered Main
Inside Stack Constructor: Stack initialized
The popped element is: 9
As seen above, the stack object is initialized automatically at the time of creation by the constructor. So we don’t need to write and invoke initialization functions explicitly.
What are destructors?
- Destructors are complements of constructors.
- When an object is destroyed, its destructor is automatically called.
- Destructors are mainly useful for doing the clean up job.
- An object may have allocated some memory during its lifetime; destructors are the place where this memory is deallocated.
- Or an object may need to close some files by releasing its handles which it had previously obtained.
- Destructor function has same name as that of a constructor; but the name is preceded by a tilde (‘~’) sign.
We will expand the above example of a stack class to include a destructor:
#include <iostream>
using namespace std;
class stack
{
int top, bottom;
int data[20];
stack() //constructor function
{
top = bottom;
cout <<”Inside Stack Constructor: Stack initialized\n”;
}
int stackfull()
{
return ((top == max – 1)?1:0);
}
int stackempty()
{
return (top == bottom)?1:0);
}
void push(int no)
{
if(stackfull())
cout<<”Stack is full”;
else
data[++top] = no;
}
int pop()
{
if(stackempty())
cout<<”Nothing to pop.. Stack is Empty!\n”;
else
return(data[top- -]);
}
~stack() //destructor function
{
cout <<”Inside Stack Destructor: Stack Destroyed\n”;
}
};
int main()
{
int i, no;
stack st; //object is created; hence constructor is invoked- stack initialization done
cout <<”Entered Main\n”;
for(i = 0; i < 10; i++)
st.push(i);
no = s.pop();
cout <<”The popped element is:”<<no << “\n”;
return 0;
} // at the end of object’s lifetime, destructor is invoked
The output of the program would be:
Entered Main
Inside Stack Constructor: Stack initialized
The popped element is: 9
Inside Stack Destructor: Stack Destroyed
As seen from the o/p the constructors and destructors are automatically called.
What is friend class in C++?
- When a class declares another class as its friend, it is giving complete access to all its data and methods including private and protected data and methods to the friend class member methods.
- Friendship between classes is one way only, which means if A declares B as its friend it does not mean that A can access private data of B.
- It only means that B can access all data of A.
Syntax of friend class:
friend class classname;
- A keyword friend is used to declare a variable.
What is multiple inheritance?
- When a class is derived from another class i.e. it inherits functionalities of another class, this phenomenon is known as inheritance.
- In some cases, a class can inherit from multiple classes, i.e. a derived class can have multiple base classes, it is known as multiple inheritance.
Consider the following example:
class Base1
{
private:
int no1;
public:
void show1()
{
cout << “The number is:” << no1 <<”\n”;
}
};
class Base2
{
private:
int no2;
public:
void show2()
{
cout << “The number is:” << no2 <<”\n”;
}
};
class Derived: public Base1, public Base2 //Multiple inheritance
{
public:
void set(int x, int y)
{
no1 = x; no2 = y;
}
};
int main()
{
Derived ob;
ob.set(10, 20);
ob.show1(); // Derived class obj can access member functions of both base classes
ob2.show2(); //Derived class obj can access member functions of both base class return 0;
}
Explain why and when do we use protected instead of private.
- Private data members cannot be accessed outside the class.
- When a class inherits a base class, all the data members except the private get inherited into it. So if we want data members to be accessible to only derived classes and not privately or publicly accessible, then we can use protected.
- Protected is similar to private.
- It makes class member inaccessible outside the class, but the members can be accessed by any subclass of that class.
What are Iterators?
- Iterators are the ones that hold the container and algorithms together. They provide an abstract view of data so that the writer of algorithm need not be concerned with concrete details of a myriad of data structures.
- At the same time, the standard model of data access provided by iterators relieves the containers from having to provide a more extensive set of access operations.
- An iterator is simply an abstract of the notion of a pointer to an element of a sequence.
The key concepts of iterator are:
1. The element currently pointed to.
2. Point to next element.
3. Equality.
- The iterator classes and functions are declared in namespace std and found in <iterator>.
- The iterator is not a general pointer. Hence there is no concept of ‘null iterator’. The test is to determine whether an iterator points to an element or not is done by comparing it against the end of its sequence. An iterator which points to an element is said to be valid and can be dereferenced using *, [] or →.
What are default arguments in functions?
- C++ allows a function to assign a parameter a default value when no argument corresponding to that parameter is specified in a call to that function. The default value is specified in a manner syntactically similar to a variable initialization.
- For example, this declares MyFunction as taking one int argument with a default value of 0.
Void MyFunction(int i =0)
{
//…
//…
}
Now, this MyFunction() can be called one of the following two ways:
MyFunction(10); //passing explicit value
MyFunction(); //not passing any value;
- Function will give default value- One of the reasons why default arguments are included in C++ is because they provide another method for the programmer to manage greater complexity.
- To handle the widest variety of situations, quite frequently a function contains more parameters than are required for its most common usage.
- Thus, when the default arguments apply, you need to specify only the arguments that are meaningful to the exact situation, not all those needed by the most general case.
Explain the use of this pointer.
- When a member function is called, it is automatically passed an implicit argument that is a pointer to the invoking objects (i.e. the object on which the function is invoked). This pointer is known as 'this' pointer. It is internally created at the time of function call.
- The this pointer is very important when operators are overloaded.
- Example: Consider a class with int and float data members and overloaded Pre-increment operator ++.
class MyClass
{
int i;
float f;
public:
MyClass ()
{
i = 0;
f = 0.0;
}
MyClass (int x, float y)
{
i = x; f = y;
}
MyClass operator ++()
{
i = i + 1;
f = f + 1.0;
return *this; //this pointer which points to the caller object
}
MyClass show()
{
cout<<”The elements are:\n” cout<<i<<”\n<f; //accessing data members using this
}
};
int main()
{
MyClass a;
++a; //The overloaded operator function ++()will return a’s this pointer
a.show();
retun 0;
}
The output would be
The elements are:
1
1.0
What is function template?
- Function template defines a general set of operations that will be applied to various types of data.
- The type of data that the function will operate upon is passed to it as a parameter.
- Through a generic function, a single general procedure can be applied to a wide range of data.
- Depending on the program, the compiler creates different versions of function template associated with different data types.
- Generic function is created using the keyword template.
- It is used to create a template that describes what a function will do. E.g. we can write a function template that swaps two numbers.
- We can use the same template to swap two ints, two floats or even two chars.
Consider the following example:
#include <iostream>
template <class X> void swap(X &a, X &b) // ? Function template
{
X temp;
temp = a;
a = b;
b = temp;
}
int main()
{
int i = 10, j = 20;
float x = 4.5, y = 8.7;
char a = ‘A’, b = ‘B’;
cout << “Original i and j are : “<< i << ‘ ‘ << j << ‘\n’;
cout << “Original x and y are : “<< x << ‘ ‘ << y << ‘\n’;
cout << “Original a and b are : “<< a << ‘ ‘ << b << ‘\n’;
swap(i, j); // we can call the same function with different parameters
swap(x, y); // Compiler has created 3 version of template function
swap(a, b); //The correct version will be called depending on parameters passed
cout << “Swapped i and j are : “<< i << ‘ ‘ << j << ‘\n’;
cout << “Swapped x and y are : “<< x << ‘ ‘ << y << ‘\n’;
cout << “Swapped a and b are : “<< a << ‘ ‘ << b << ‘\n’;
return 0;
}
Exception handling concept.
- Exceptions are certain disastrous error conditions that occur during the execution of a program.
- They could be errors that cause the programs to fail or certain conditions that lead to errors. If these run time errors are not handled by the program, OS handles them and program terminates abruptly, which is not good.
- To avoid this, C++ provides Exception Handling mechanism.
- The three keywords for Exception Handling are: Try, Catch and Throw.
- The program tries to do something. If it encounters some problem, it throws an exception to another program block which catches the exception.
Example:
void main()
{
int no1, no2;
try
{
cout << “Enter two nos:”;
cin >> no1 >> no2;
if (no2 == 0)
throw “Divide by zero”;
else
throw no1/no2;
}
catch (char *s)
{
cout << s;
}
catch (int ans)
{
cout << ans;
}
}
We know that divide by zero is an exception. If user enters second no as zero, the program throws an exception, which is caught and an error message is printed else the answer is printed.
What is inline function?
- An inline function is a combination of macro & function. At the time of declaration or definition, function name is preceded by word inline.
- When inline functions are used, the overhead of function call is eliminated. Instead, the executable statements of the function are copied at the place of each function call. This is done by the compiler.
Consider the following example:
#include <iostream>
using namespace std;
inline int sqr(int x)
{
int y;
y = x * x;
return y;
}
int main()
{
int a =3, b;
b = sqr(a);
cout <<b;
return 0;
}
- Here, the statement b = sqr(a) is a function call to sqr(). But since we have declared it as inline, the compiler replaces the statement with the executable statement of the function (b = a *a).
- Please note that, inline is a request to the compiler. If it is very complicated function, compiler may not be able to convert it to inline. Then it will remain as it is.
- Example, Recursive function, function containing static variable, function containing return statement or loop or goto or switch statements are not made inline even if we declare them so.
- Also, small functions which are defined inside a class (i.e their code is written inside the class) are taken as inline by the compiler even if we don’t explicitly declare them so. They are called auto inline functions.
What are pure virtual functions?
A pure virtual function is a function which has no definition in the base class. Its definition lies only in the derived class i.e. it is compulsory for the derived class to provide definition of a pure virtual function. Since there is no definition in the base class, these functions can be equated to zero.
The general form of pure virtual function is:
virtual type func-name(parameter-list) = 0;
Consider the following example of base class Shape and classes derived from it viz Circle, Rectangle, Triangle etc.
class Shape
{
int x, y;
public:
virtual void draw() = 0;
};
class Circle: public Shape
{
public:
draw()
{
//Code for drawing a circle
}
};
class Rectangle : public Shape
{
Public:
void draw()
{
//Code for drawing a rectangle
}
};
class Triangle : public Shape
{
Public:
void draw()
{
//Code for drawing a triangle
}
};
Thus, base class Shape has pure virtual function draw(); which is overridden by all the derived classes.Describe new operator and delete operator.
Consider the following program:
#include <iostream>
#include <new>
using namespace std;
int main()
{
int *p;
try
{
p = new int; //dynamic allocation of memory
}
catch (bad_alloc x)
{
cout << “Memory allocation failed”;
return 1;
}
*p = 100;
cout <<”P has value”<<*p;
delete p; //free the dynamically allocated memory
return 0;
}
What is NULL pointer and void pointer and what is their use?
- A NULL pointer has a fixed reserved value that is not zero or space, which indicates that no object is referred. NULL pointers are used in C and C++ as compile-time constant. NULL pointer represents certain conditions, like successor to the last element in linked list, while a consistent structure of the list of nodes are maintained.
- A void pointer is a special pointer that points to an unspecified object. A null pointer cannot be dereferenced. The address manipulation can directly be done by pointer casting to and from an integral type of sufficient size.