C Programming
C Programming
Functions are used to perform certain actions, and they are important for reusing code: Define the code
once, and use it many times.
Predefined Functions
So it turns out you already know what a function is. You have been using it the whole time while studying
this tutorial!
For example, main() is a function, which is used to execute code, and printf() is a function; used to output/print
text to the screen:
Example
int main() {
printf("Hello World!");
return 0;
}
Create a Function
To create (often referred to as declare) your own function, specify the name of the function, followed by
parentheses () and curly brackets {}:
Syntax
void myFunction() {
// code to be executed
}
Example Explained
myFunction() is the name of the function
void means that the function does not have a return value. You will learn more about return values
later in the next chapter
Inside the function (the body), add code that defines what the function should do
Call a Function
Declared functions are not executed immediately. They are "saved for later use", and will be executed when
they are called.
To call a function, write the function's name followed by two parentheses () and a semicolon ;
In the following example, myFunction() is used to print a text (the action), when it is called:
Example
Inside main, call myFunction():
// Create a function
void myFunction() {
printf("I just got executed!");
}
int main() {
myFunction(); // call the function
return 0;
}
int main() {
myFunction();
myFunction();
myFunction();
return 0;
}
C Function Parameters
Parameters and Arguments
Information can be passed to functions as a parameter. Parameters act as variables inside the function.
Parameters are specified after the function name, inside the parentheses. You can add as many parameters as
you want, just separate them with a comma:
Syntax
returnType functionName(parameter1, parameter2, parameter3) {
// code to be executed
}
The following function that takes a string of characters with name as parameter. When the function is called,
we pass along a name, which is used inside the function to print "Hello" and the name of each person.
Example
void myFunction(char name[]) {
printf("Hello %s\n", name);
}
int main() {
myFunction("Liam");
myFunction("Jenny");
myFunction("Anja");
return 0;
}
// Hello Liam
// Hello Jenny
// Hello Anja
When a parameter is passed to the function, it is called an argument. So, from the example above: name is
a parameter, while Liam, Jenny and Anja are arguments.
Multiple Parameters
Inside the function, you can add as many parameters as you want:
Example
void myFunction(char name[], int age) {
printf("Hello %s. You are %d years old.\n", name, age);
}
int main() {
myFunction("Liam", 3);
myFunction("Jenny", 14);
myFunction("Anja", 30);
return 0;
}
Note that when you are working with multiple parameters, the function call must have the same number of
arguments as there are parameters, and the arguments must be passed in the same order.
Example
void myFunction(int myNumbers[5]) {
for (int i = 0; i < 5; i++) {
printf("%d\n", myNumbers[i]);
}
}
int main() {
int myNumbers[5] = {10, 20, 30, 40, 50};
myFunction(myNumbers);
return 0;
}
Example Explained
The function (myFunction) takes an array as its parameter (int myNumbers[5]), and loops through the array
elements with the for loop.
When the function is called inside main(), we pass along the myNumbers array, which outputs the array
elements.
Note that when you call the function, you only need to use the name of the array when passing it as an
argument myFunction(myNumbers). However, the full declaration of the array is needed in the function
parameter (int myNumbers[5]).
Return Values
The void keyword, used in the previous examples, indicates that the function should not return a value. If you
want the function to return a value, you can use a data type (such as int or float, etc.) instead of void, and use
the return keyword inside the function:
Example
int myFunction(int x) {
return 5 + x;
}
int main() {
printf("Result is: %d", myFunction(3));
return 0;
}
// Outputs 8 (5 + 3)
Example
int myFunction(int x, int y) {
return x + y;
}
int main() {
printf("Result is: %d", myFunction(5, 3));
return 0;
}
// Outputs 8 (5 + 3)
Example
int myFunction(int x, int y) {
return x + y;
}
int main() {
int result = myFunction(5, 3);
printf("Result is = %d", result);
return 0;
}
// Outputs 8 (5 + 3)
Real-Life Example
To demonstrate a practical example of using functions, let's create a program that converts a value from
fahrenheit to celsius:
Example
// Function to convert Fahrenheit to Celsius
float toCelsius(float fahrenheit) {
return (5.0 / 9.0) * (fahrenheit - 32.0);
}
int main() {
// Set a fahrenheit value
float f_value = 98.8;
return 0;
}
Example
// Create a function
void myFunction() {
printf("I just got executed!");
}
int main() {
myFunction(); // call the function
return 0;
}
Declaration: the function's name, return type, and parameters (if any)
Definition: the body of the function (code to be executed)
For code optimization, it is recommended to separate the declaration and the definition of the function.
You will often see C programs that have function declaration above main(), and function definition
below main(). This will make the code better organized and easier to read:
Example
// Function declaration
void myFunction();
// The main method
int main() {
myFunction(); // call the function
return 0;
}
// Function definition
void myFunction() {
printf("I just got executed!");
}
Another Example
If we use the example from the previous chapter regarding function parameters and return values:
Example
int myFunction(int x, int y) {
return x + y;
}
int main() {
int result = myFunction(5, 3);
printf("Result is = %d", result);
return 0;
}
// Outputs 8 (5 + 3)
Example
// Function declaration
int myFunction(int, int);
// Function definition
int myFunction(int x, int y) {
return x + y;
}
Recursion
Recursion is the technique of making a function call itself. This technique provides a way to break
complicated problems down into simple problems which are easier to solve.
Recursion may be a bit difficult to understand. The best way to figure out how it works is to experiment with
it.
Recursion Example
Adding two numbers together is easy to do, but adding a range of numbers is more complicated. In the
following example, recursion is used to add a range of numbers together by breaking it down into the simple
task of adding two numbers:
Example
int sum(int k);
int main() {
int result = sum(10);
printf("%d", result);
return 0;
}
int sum(int k) {
if (k > 0) {
return k + sum(k - 1);
} else {
return 0;
}
}
Example Explained
When the sum() function is called, it adds parameter k to the sum of all numbers smaller than k and returns
the result. When k becomes 0, the function just returns 0. When running, the program follows these steps:
10 + sum(9)
10 + ( 9 + sum(8) )
10 + ( 9 + ( 8 + sum(7) ) )
...
10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + sum(0)
10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0
Since the function does not call itself when k is 0, the program stops there and returns the result.
The developer should be very careful with recursion as it can be quite easy to slip into writing a function
which never terminates, or one that uses excess amounts of memory or processor power. However, when
written correctly, recursion can be a very efficient and mathematically-elegant approach to programming.
Math Functions
There is also a list of math functions available, that allows you to perform mathematical tasks on numbers.
To use them, you must include the math.h header file in your program:
#include <math.h>
Square Root
To find the square root of a number, use the sqrt() function:
Example
printf("%f", sqrt(16));
Round a Number
The ceil() function rounds a number upwards to its nearest integer, and the floor() method rounds a number
downwards to its nearest integer, and returns the result:
Example
printf("%f", ceil(1.4));
printf("%f", floor(1.4));
Power
The pow() function returns the value of x to the power of y (xy):
Example
printf("%f", pow(4, 3));
Function Description
Nested functions in C
Some programmer thinks that defining a function inside an another function is known as “nested
function”. But the reality is that it is not a nested function, it is treated as lexical scoping.
Lexical scoping is not valid in C because the compiler cant reach/find the correct memory
location of the inner function.
Nested function is not supported by C because we cannot define a function within another
function in C. We can declare a function inside a function, but it’s not a nested function.
Because nested functions definitions can not access local variables of the surrounding blocks,
they can access only global variables of the containing module. This is done so that lookup of
global variables doesn’t have to go through the directory. As in C, there are two nested scopes:
local and global (and beyond this, built-ins). Therefore, nested functions have only a limited use.
If we try to approach nested function in C, then we will get compile time error.
#include <stdio.h>
int main(void)
printf("Main");
int fun()
printf("fun");
// defining view() function inside fun() function.
int view()
printf("view");
return 1;
view();
Output:
Compile time error: undefined reference to `view'
An extension of the GNU C Compiler allows the declarations of nested functions. The
declarations of nested functions under GCC’s extension need to be prefix/start with the auto
keyword.
#include <stdio.h>
int main(void)
printf("Main\n");
int view()
printf("View\n");
return 1;
printf("GEEKS");
return 0;
Output:
view
Main
GEEKS
Way-1
Formal parameters as a pointer −
Way-3
Formal parameters as an unsized array −
Example
Now, consider the following function, which takes an array as an argument along with
another argument and based on the passed arguments, it returns the average of the numbers
passed through the array as follows −
int i;
double avg;
double sum = 0;
return avg;
}
#include <stdio.h>
/* function declaration */
double getAverage(int arr[], int size);
int main () {
return 0;
}
When the above code is compiled together and executed, it produces the following result −
As you can see, the length of the array doesn't matter as far as the function is concerned
because C performs no bounds checking for formal parameters.
The command line arguments are handled using main() function arguments
where argc refers to the number of arguments passed, and argv[] is a pointer array which
points to each argument passed to the program. Following is a simple example which checks
if there is any argument supplied from the command line and take action accordingly −
#include <stdio.h>
if( argc == 2 ) {
printf("The argument supplied is %s\n", argv[1]);
}
else if( argc > 2 ) {
printf("Too many arguments supplied.\n");
}
else {
printf("One argument expected.\n");
}
}
When the above code is compiled and executed with single argument, it produces the
following result.
$./a.out testing
The argument supplied is testing
When the above code is compiled and executed with a two arguments, it produces the
following result.
When the above code is compiled and executed without passing any argument, it produces
the following result.
$./a.out
One argument expected
It should be noted that argv[0] holds the name of the program itself and argv[1] is a pointer
to the first command line argument supplied, and *argv[n] is the last argument. If no
arguments are supplied, argc will be one, and if you pass one argument then argc is set at 2.
You pass all the command line arguments separated by a space, but if argument itself has a
space then you can pass such arguments by putting them inside double quotes "" or single
quotes ''. Let us re-write above example once again where we will print program name and
we also pass a command line argument by putting inside double quotes −
#include <stdio.h>
if( argc == 2 ) {
printf("The argument supplied is %s\n", argv[1]);
}
else if( argc > 2 ) {
printf("Too many arguments supplied.\n");
}
else {
printf("One argument expected.\n");
}
}
When the above code is compiled and executed with a single argument separated by space
but inside double quotes, it produces the following result.
C Pointers
Pointers are one of the core components of the C programming language. A pointer can be used
to store the memory address of other variables, functions, or even other pointers. The use of
pointers allows low-level memory access, dynamic memory allocation, and many other
functionality in C.
In this article, we will discuss C pointers in detail, their types, uses, advantages, and
disadvantages with examples.
What is a Pointer in C?
A pointer is defined as a derived data type that can store the address of other C variables or a
memory location. We can access and manipulate the data stored in that memory location using
pointers.
As the pointers in C store the memory addresses, their size is independent of the type of data
they are pointing to. This size of pointers in C only depends on the system architecture.
Syntax of C Pointers
The syntax of pointers is similar to the variable declaration in C, but we use the ( * )
dereferencing operator in the pointer declaration.
datatype * ptr;
where
ptr is the name of the pointer.
datatype is the type of data it is pointing to.
The above syntax is used to define a pointer to a variable. We can also define pointers to
functions, structures, etc.
How to Use Pointers?
The use of pointers in C can be divided into three steps:
1. Pointer Declaration
2. Pointer Initialization
3. Pointer Dereferencing
1. Pointer Declaration
In pointer declaration, we only declare the pointer but do not initialize it. To declare a pointer,
we use the ( * ) dereference operator before its name.
Example
int *ptr;
The pointer declared here will point to some random memory address as it is not initialized.
Such pointers are called wild pointers.
2. Pointer Initialization
Pointer initialization is the process where we assign some initial value to the pointer variable.
We generally use the ( & ) addressof operator to get the memory address of a variable and then
store it in the pointer variable.
Example
int var = 10;
int * ptr;
ptr = &var;
We can also declare and initialize the pointer in a single step. This method is called pointer
definition as the pointer is declared and initialized at the same time.
Example
int *ptr = &var;
Note: It is recommended that the pointers should always be initialized to some value before
starting using it. Otherwise, it may lead to number of errors.
3. Pointer Dereferencing
Dereferencing a pointer is the process of accessing the value stored in the memory address
specified in the pointer. We use the same ( * ) dereferencing operator that we used in the
pointer declaration.
Dereferencing a Pointer in C
C Pointer Example
C
void geeks()
int* ptr;
ptr = &var;
// Driver program
int main()
geeks();
return 0;
Output
Value at ptr = 0x7fff1038675c
Value at var = 10
Value at *ptr = 10
Types of Pointers in C
Pointers in C can be classified into many different types based on the parameter on which we are
defining their types. If we consider the type of variable stored in the memory location pointed by
the pointer, then the pointers can be classified into the following types:
1. Integer Pointers
As the name suggests, these are the pointers that point to the integer values.
Syntax
int *ptr;
These pointers are pronounced as Pointer to Integer.
Similarly, a pointer can point to any primitive data type. It can point also point to derived data
types such as arrays and user-defined data types such as structures.
2. Array Pointer
Pointers and Array are closely related to each other. Even the array name is the pointer to its
first element. They are also known as Pointer to Arrays. We can create a pointer to an array
using the given syntax.
Syntax
char *ptr = &array_name;
Pointer to Arrays exhibits some interesting properties which we discussed later in this article.
3. Structure Pointer
The pointer pointing to the structure type is called Structure Pointer or Pointer to Structure. It
can be declared in the same way as we declare the other primitive data types.
Syntax
struct struct_name *ptr;
In C, structure pointers are used in data structures such as linked lists, trees, etc.
4. Function Pointers
Function pointers point to the functions. They are different from the rest of the pointers in the
sense that instead of pointing to the data, they point to the code. Let’s consider a function
prototype – int func (int, char), the function pointer for this function will be
Syntax
int (*ptr)(int, char);
Note: The syntax of the function pointers changes according to the function prototype.
5. Double Pointers
In C language, we can define a pointer that stores the memory address of another pointer. Such
pointers are called double-pointers or pointers-to-pointer. Instead of pointing to a data value,
they point to another pointer.
Syntax
datatype ** pointer_name;
Dereferencing Double Pointer
*pointer_name; // get the address stored in the inner level pointer
**pointer_name; // get the value pointed by inner level pointer
Note: In C, we can create multi-level pointers with any number of levels such as – ***ptr3,
****ptr4, ******ptr5 and so on.
6. NULL Pointer
The Null Pointers are those pointers that do not point to any memory location. They can be
created by assigning a NULL value to the pointer. A pointer of any type can be assigned the
NULL value.
Syntax
data_type *pointer_name = NULL;
or
pointer_name = NULL
It is said to be good practice to assign NULL to the pointers currently not in use.
7. Void Pointer
The Void pointers in C are the pointers of type void. It means that they do not have any
associated data type. They are also called generic pointers as they can point to any type and can
be typecasted to any type.
Syntax
void * pointer_name;
One of the main properties of void pointers is that they cannot be dereferenced.
8. Wild Pointers
The Wild Pointers are pointers that have not been initialized with something yet. These types of
C-pointers can cause problems in our programs and can eventually cause them to crash.
Example
int *ptr;
char *str;
9. Constant Pointers
In constant pointers, the memory address stored inside the pointer is constant and cannot be
modified once it is defined. It will always point to the same memory address.
Syntax
data_type * const pointer_name;
10. Pointer to Constant
The pointers pointing to a constant value that cannot be modified are called pointers to a
constant. Here we can only access the data pointed by the pointer, but cannot modify it.
Although, we can change the address stored in the pointer to constant.
Syntax
const data_type * pointer_name;
Other Types of Pointers in C:
There are also the following types of pointers available to use in C apart from those specified
above:
Far pointer: A far pointer is typically 32-bit that can access memory outside the current
segment.
Dangling pointer: A pointer pointing to a memory location that has been deleted (or freed)
is called a dangling pointer.
Huge pointer: A huge pointer is 32-bit long containing segment address and offset address.
Complex pointer: Pointers with multiple levels of indirection.
Near pointer: Near pointer is used to store 16-bit addresses means within the current
segment on a 16-bit machine.
Normalized pointer: It is a 32-bit pointer, which has as much of its value in the segment
register as possible.
File Pointer: The pointer to a FILE data type is called a stream pointer or a file pointer.
Size of Pointers in C
The size of the pointers in C is equal for every pointer type. The size of the pointer does not
depend on the type it is pointing to. It only depends on the operating system and CPU
architecture. The size of pointers in C is
8 bytes for a 64-bit System
4 bytes for a 32-bit System
The reason for the same size is that the pointers store the memory addresses, no matter what
type they are. As the space required to store the addresses of the different memory locations is
the same, the memory required by one pointer type will be equal to the memory required by
other pointer types.
How to find the size of pointers in C?
We can find the size of pointers using the sizeof operator as shown in the following program:
Example: C Program to find the size of different pointer types.
C
#include <stdio.h>
// dummy structure
struct str {
};
// dummy function
int main()
{
int a = 10;
char c = 'G';
struct str x;
// printing sizes
sizeof(ptr_int));
sizeof(ptr_char));
sizeof(ptr_str));
sizeof(ptr_func));
printf("Size of NULL Void Pointer\t:\t%d bytes",
sizeof(ptr_vn));
return 0;
Output
Size of Integer Pointer : 8 bytes
Size of Character Pointer : 8 bytes
Size of Structure Pointer : 8 bytes
Size of Function Pointer : 8 bytes
Size of NULL Void Pointer : 8 bytes
As we can see, no matter what the type of pointer it is, the size of each and every pointer is the
same.
Now, one may wonder that if the size of all the pointers is the same, then why do we need to
declare the pointer type in the declaration? The type declaration is needed in the pointer for
dereferencing and pointer arithmetic purposes.
C Pointer Arithmetic
The Pointer Arithmetic refers to the legal or valid arithmetic operations that can be performed
on a pointer. It is slightly different from the ones that we generally use for mathematical
calculations as only a limited set of operations can be performed on pointers. These operations
include:
Increment in a Pointer
Decrement in a Pointer
Addition of integer to a pointer
Subtraction of integer to a pointer
Subtracting two pointers of the same type
Comparison of pointers of the same type.
Assignment of pointers of the same type.
C
int main()
// Declare an array
int* ptr;
ptr = v;
ptr++;
return 0;
Output
Value of *ptr = 10
Value of ptr = 0x7ffe8ba7ec50
C
void geeks()
// Declare an array
int* ptr;
ptr = val;
return;
// Driver program
int main()
geeks();
return 0;
Output
Elements of the array are: 5 10 15
Not only that, as the array elements are stored continuously, we can pointer arithmetic
operations such as increment, decrement, addition, and subtraction of integers on pointer to
move between array elements.
Example 2: Accessing Array Elements using Pointer Arithmetic
C
#include <stdio.h>
int main()
{
// defining array
int arr[5] = { 1, 2, 3, 4, 5 };
return 0;
Output
12345
This concept is not limited to the one-dimensional array, we can refer to a multidimensional
array element as well using pointers.
To know more about pointers to an array, refer to this article – Pointer to an Array
Uses of Pointers in C
The C pointer is a very powerful tool that is widely used in C programming to perform various
useful operations. It is used to achieve the following functionalities in C:
1. Pass Arguments by Reference
2. Accessing Array Elements
3. Return Multiple Values from Function
4. Dynamic Memory Allocation
5. Implementing Data Structures
6. In System-Level Programming where memory addresses are useful.
7. In locating the exact value at some memory location.
8. To avoid compiler confusion for the same variable name.
9. To use in Control Tables.
Advantages of Pointers
Following are the major advantages of pointers in C:
Pointers are used for dynamic memory allocation and deallocation.
An Array or a structure can be accessed efficiently with pointers
Pointers are useful for accessing memory locations.
Pointers are used to form complex data structures such as linked lists, graphs, trees, etc.
Pointers reduce the length of the program and its execution time as well.
Disadvantages of Pointers
Pointers are vulnerable to errors and have following disadvantages:
Memory corruption can occur if an incorrect value is provided to pointers.
Pointers are a little bit complex to understand.
Pointers are majorly responsible for memory leaks in C.
Pointers are comparatively slower than variables in C.
Uninitialized pointers might cause a segmentation fault.
Conclusion
In conclusion, pointers in C are very capable tools and provide C language with its
distinguishing features, such as low-level memory access, referencing, etc. But as powerful as
they are, they should be used with responsibility as they are one of the most vulnerable parts of
the language.
C/C++ Preprocessors
Preprocessors are programs that process the source code before compilation. A number of steps
are involved between writing a program and executing a program in C / C++. Let us have a look
at these steps before we actually start learning about Preprocessors.
You can see the intermediate steps in the above diagram. The source code written by
programmers is first stored in a file, let the name be “program.c“. This file is then processed by
preprocessors and an expanded source code file is generated named “program.i”. This expanded
file is compiled by the compiler and an object code file is generated named “program.obj”.
Finally, the linker links this object code file to the object code of the library functions to
generate the executable file “program.exe”.
Preprocessor Directives in C/C++
Preprocessor programs provide preprocessor directives that tell the compiler to preprocess the
source code before compiling. All of these preprocessor directives begin with a ‘#’ (hash)
symbol. The ‘#’ symbol indicates that whatever statement starts with a ‘#’ will go to the
preprocessor program to get executed. We can place these preprocessor directives anywhere in
our program.
Examples of some preprocessor directives are: #include, #define, #ifndef, etc.
Note: Remember that the # symbol only provides a path to the preprocessor, and a command
such as include is processed by the preprocessor program. For example, #include will include
the code or content of the specified file in your program.
The following table lists all the preprocessor directives in C/C++:
Preprocessor
Description
Directives
These preprocessors can be classified based on the type of function they perform.
1. Macros
In C/C++, Macros are pieces of code in a program that is given some name. Whenever this name
is encountered by the compiler, the compiler replaces the name with the actual piece of code.
The ‘#define’ directive is used to define a macro.
Example of Macro
C
C++
#include <stdio.h>
// macro definition
#define LIMIT 5
int main()
return 0;
Output
0
1
2
3
4
In the above program, when the compiler executes the word LIMIT, it replaces it with 5. The
word ‘LIMIT’ in the macro definition is called a macro template and ‘5’ is macro expansion.
Note: There is no semi-colon (;) at the end of the macro definition. Macro definitions do not
need a semi-colon to end.
There are also some Predefined Macros in C which are useful in providing various
functionalities to our program.
We can also pass arguments to macros. Macros defined with arguments work similarly to
functions.
Example
#define foo(a, b) a + b
#define func(r) r * r
Let us understand this with a program:
C
C++
#include <stdio.h>
#define AREA(l, b) (l * b)
int main()
{
int l1 = 10, l2 = 5, area;
return 0;
Output
Area of rectangle is: 50
We can see from the above program that whenever the compiler finds AREA(l, b) in the
program, it replaces it with the statement (l*b). Not only this, but the values passed to the macro
template AREA(l, b) will also be replaced in the statement (l*b). Therefore AREA(10, 5) will be
equal to 10*5.
2. File Inclusion
This type of preprocessor directive tells the compiler to include a file in the source code
program. The #include preprocessor directive is used to include the header files in the C/C++
program.
There are two types of files that can be included by the user in the program:
Standard Header Files
The standard header files contain definitions of pre-defined functions like printf(), scanf(), etc.
These files must be included to work with these functions. Different functions are declared in
different header files.
For example, standard I/O functions are in the ‘iostream’ file whereas functions that perform
string operations are in the ‘string’ file.
Syntax
#include <file_name>
where file_name is the name of the header file to be included. The ‘<‘ and ‘>’ brackets tell the
compiler to look for the file in the standard directory.
User-defined Header Files
When a program becomes very large, it is a good practice to divide it into smaller files and
include them whenever needed. These types of files are user-defined header files. These files
can be included as:
#include "filename"
The double quotes ( ” ” ) tell the compiler to search for the header file in the source file’s
directory.
3. Conditional Compilation
Conditional Compilation in C/C++ directives is a type of directive that helps to compile a
specific portion of the program or to skip the compilation of some specific part of the program
based on some conditions. There are the following preprocessor directives that are used to insert
conditional code:
1. #if Directive
2. #ifdef Directive
3. #ifndef Directive
4. #else Directive
5. #elif Directive
6. #endif Directive
#endif directive is used to close off the #if, #ifdef, and #ifndef opening directives which means
the preprocessing of these directives is completed.
Syntax
#ifdef macro_name
statement1;
statement2;
statement3;
.
.
.
statementN;
#endif
If the macro with the name ‘macro_name‘ is defined, then the block of statements will execute
normally, but if it is not defined, the compiler will simply skip this block of statements.
4. Other Directives
Apart from the above directives, there are two more directives that are not commonly used.
These are:
1. #undef Directive
2. #pragma Directive
1. #undef Directive
The #undef directive is used to undefine an existing macro. This directive works as:
#undef LIMIT
Using this statement will undefine the existing macro LIMIT. After this statement, every “#ifdef
LIMIT” statement will evaluate as false.
2. #pragma Directive
This directive is a special purpose directive and is used to turn on or off some features. These
types of directives are compiler-specific, i.e., they vary from compiler to compiler. Some of the
#pragma directives are discussed below:
1. #pragma startup: These directives help us to specify the functions that are needed to run
before program startup (before the control passes to main()).
2. #pragma exit: These directives help us to specify the functions that are needed to run just
before the program exit (just before the control returns from main()).
Note: Below program will not work with GCC compilers.
Example
C
C++
// startup
#include <stdio.h>
void func1();
void func2();
// driver code
int main()
{
void func1();
void func2();
printf("Inside main()\n");
return 0;
Output
Inside main()
Expected Output
Inside func1()
Inside main()
Inside func2()
The above code will produce the output as given below when run on GCC compilers:
Inside main()
This happens because GCC does not support #pragma startup or exit. However, you can use the
below code for the expected output on GCC compilers.
C++
C
#include <iostream>
void func1();
void func2();
void func1()
printf("Inside func1()\n");
void func2()
printf("Inside func2()\n");
// Driver code
int main()
printf("Inside main()\n");
return 0;
Output
Inside func1()
Inside main()
Inside func2()
In the above program, we have used some specific syntaxes so that one of the functions executes
before the main function and the other executes after the main function.
#pragma warn Directive
This directive is used to hide the warning message which is displayed during compilation. We
can hide the warnings as shown below:
#pragma warn -rvl: This directive hides those warnings which are raised when a function
that is supposed to return a value does not return a value.
#pragma warn -par: This directive hides those warnings which are raised when a function
does not use the parameters passed to it.
#pragma warn -rch: This directive hides those warnings which are raised when a code is
unreachable. For example, any code written after the return statement in a function is
unreachable
Storage Classes in C
C Storage Classes are used to describe the features of a variable/function. These features
basically include the scope, visibility, and lifetime which help us to trace the existence of a
particular variable during the runtime of a program.
C language uses 4 storage classes, namely:
1. auto
This is the default storage class for all the variables declared inside a function or a block. Hence,
the keyword auto is rarely used while writing programs in C language. Auto variables can be
only accessed within the block/function they have been declared and not outside them (which
defines their scope). Of course, these can be accessed within nested blocks within the parent
block/function in which the auto variable was declared.
However, they can be accessed outside their scope as well using the concept of pointers given
here by pointing to the very exact memory location where the variables reside. They are
assigned a garbage value by default whenever they are declared.
2. extern
Extern storage class simply tells us that the variable is defined elsewhere and not within the
same block where it is used. Basically, the value is assigned to it in a different block and this can
be overwritten/changed in a different block as well. So an extern variable is nothing but a global
variable initialized with a legal value where it is declared in order to be used elsewhere. It can be
accessed within any function/block.
Also, a normal global variable can be made extern as well by placing the ‘extern’ keyword
before its declaration/definition in any function/block. This basically signifies that we are not
initializing a new variable but instead, we are using/accessing the global variable only. The main
purpose of using extern variables is that they can be accessed between two different files which
are part of a large program.
3. static
This storage class is used to declare static variables which are popularly used while writing
programs in C language. Static variables have the property of preserving their value even after
they are out of their scope! Hence, static variables preserve the value of their last use in their
scope. So we can say that they are initialized only once and exist till the termination of the
program. Thus, no new memory is allocated because they are not re-declared.
Their scope is local to the function to which they were defined. Global static variables can be
accessed anywhere in the program. By default, they are assigned the value 0 by the compiler.
4. register
This storage class declares register variables that have the same functionality as that of the auto
variables. The only difference is that the compiler tries to store these variables in the register of
the microprocessor if a free register is available. This makes the use of register variables to be
much faster than that of the variables stored in the memory during the runtime of the program.
If a free registration is not available, these are then stored in the memory only. Usually, a few
variables which are to be accessed very frequently in a program are declared with the register
keyword which improves the running time of the program. An important and interesting point to
be noted here is that we cannot obtain the address of a register variable using pointers.
Syntax
To specify the storage class for a variable, the following syntax is to be followed:
storage_class var_data_type var_name;
Declaration of Structure Variable
Sure, declaring a structure variable in C is pretty straightforward. First, you'll need to define the
structure using the struct keyword, and then you can declare a variable of that structure type. Here's a
simple example:
#include <stdio.h>
// Define the structure
struct Point {
int x;
int y;
};
int main() {
myPoint.x = 10;
myPoint.y = 20;
return 0;
In this example, I defined a structure named Point with two members x and y, representing coordinates.
Then, I declared a variable myPoint of type struct Point and accessed its members to set and print values.
C typedef
The typedef is a keyword that is used to provide existing data types with a new name. The C
typedef keyword is used to redefine the name of already existing data types.
When names of datatypes become difficult to use in programs, typedef is used with user-defined
datatypes, which behave similarly to defining an alias for commands.
C typedef Syntax
typedef existing_name alias_name;
After this declaration, we can use the alias_name as if it were the real existing_name in out C
program.
Example of typedef in C
typedef long long ll;
Below is the C program to illustrate how to use typedef.
C
#include <stdio.h>
// Driver code
int main()
ll var = 20;
printf("%ld", var);
return 0;
Output
20
Use of typedef in C
Following are some common uses of the typedef in C programming:
The typedef keyword gives a meaningful name to the existing data type which helps other
users to understand the program more easily.
It can be used with structures to increase code readability and we don’t have to type struct
repeatedly.
The typedef keyword can also be used with pointers to declare multiple pointers in a single
statement.
It can be used with arrays to declare any number of variables.
C Structures
Read
Discuss(20+)
Courses
Practice
Video
The structure in C is a user-defined data type that can be used to group items of possibly
different types into a single type. The struct keyword is used to define the structure in the C
programming language. The items in the structure are called its member and they can be of any
valid data type.
C Structure Declaration
We have to declare structure in C before using it in our program. In structure declaration, we
specify its member variables along with their datatype. We can use the struct keyword to declare
the structure in C using the following syntax:
Syntax
struct structure_name {
data_type member_name1;
data_type member_name1;
....
....
};
The above syntax is also called a structure template or structure prototype and no memory is
allocated to the structure in the declaration.
C Structure Definition
To use structure in our program, we have to define its instance. We can do that by creating
variables of the structure type. We can define structure variables using two methods:
struct structure_name {
data_type member_name1;
data_type member_name1;
....
....
}variable1, varaible2, ...;
Syntax
structure_name.member1;
strcuture_name.member2;
In the case where we have a pointer to the structure, we can also use the arrow operator to access
the members.
Designated Initialization allows structure members to be initialized in any order. This feature
has been added in the C99 standard.
struct structure_name str = { .member1 = value1, .member2 = value2, .member3 = value3 };
The Designated Initialization is only supported in C but not in C++.
Example of Structure in C
The following C program shows how to use structures
C
#include <stdio.h>
struct str1 {
int i;
char c;
float f;
char s[30];
};
struct str2 {
int ii;
char cc;
float ff;
// Driver code
int main()
// initializer list
var2;
var2 = var1;
printf("Struct 1:\n\ti = %d, c = %c, f = %f, s = %s\n",
var3.cc, var3.ff);
return 0;
Output
Struct 1:
i = 1, c = A, f = 1.000000, s = GeeksforGeeks
Struct 2:
i = 1, c = A, f = 1.000000, s = GeeksforGeeks
Struct 3
i = 5, c = a, f = 5.000000
Example
C
// structures
#include <stdio.h>
// defining structure
struct str1 {
int a;
};
int x;
} str2;
int main()
str1 var1 = { 20 };
return 0;
Output
var1.a = 20
var2.x = 314
Nested Structures
C language allows us to insert one structure into another as a member. This process is called
nesting and such structures are called nested structures. There are two ways in which we can
nest one structure into another:
In this method, the structure being nested is also declared inside the parent structure.
Example
struct parent {
int member1;
struct member_str member2 {
int member_str1;
char member_str2;
...
}
...
}
In this method, two structures are declared separately and then the member structure is nested
inside the parent structure.
Example
struct member_str {
int member_str1;
char member_str2;
...
}
struct parent {
int member1;
struct member_str member2;
...
}
One thing to note here is that the declaration of the structure should always be present before its
definition as a structure member. For example, the declaration below is invalid as the struct
mem is not defined when it is declared inside the parent structure.
struct parent {
struct mem a;
};
struct mem {
int var;
};
We can access nested Members by using the same ( . ) dot operator two times as shown:
str_parent.str_child.member;
C
// forward declaration
#include <stdio.h>
// child structure declaration
struct child {
int x;
char c;
};
struct parent {
int a;
struct child b;
};
// driver code
int main()
Output
var1.a = 25
var1.b.x = 195
var1.b.c = A
Structure Pointer in C
We can define a pointer that points to the structure like any other variable. Such pointers are
generally called Structure Pointers. We can access the members of the structure pointed by the
structure pointer using the ( -> ) arrow operator.
C
#include <stdio.h>
// structure declaration
struct Point {
int x, y;
};
int main()
return 0;
Output
12
Self-Referential Structures
The self-referential structures in C are those structures that contain references to the same type
as themselves i.e. they contain a member of the type pointer pointing to the same structure type.
struct structure_name {
data_type member1;
data_type member2;
struct structure_name* str;
}
C
#include <stdio.h>
// structure template
typedef struct str {
int mem1;
int mem2;
}str;
// driver code
int main()
var1.next = &var2;
// pointer to var1
ptr1->next->mem2);
return 0;
Output
var2.mem1: 10
var2.mem2: 20
Such kinds of structures are used in different data structures such as to define the nodes of
linked lists, trees, etc.
C
#include <stdio.h>
struct str1 {
char c;
int i;
};
struct str2 {
char c;
int i;
// driver code
int main()
return 0;
Output
Size of str1: 8
Size of str2: 5
As we can see, the size of the structure is varied when structure packing is performed.
To know more about structure padding and packing, refer to this article – Structure Member
Alignment, Padding and Data Packing.
Bit Fields
Bit Fields are used to specify the length of the structure members in bits. When we know the
maximum length of the member, we can use bit fields to specify the size and reduce memory
consumption.
Syntax of Bit Fields
struct structure_name {
data_type member_name: width_of_bit-field;
};
C
#include <stdio.h>
struct str1 {
int a;
char c;
};
struct str2 {
char c;
};
// driver code
int main()
return 0;
Output
Size of Str1: 8
Size of Str2: 4
As we can see, the size of the structure is reduced when using the bit field to define the max size
of the member ‘a’.
Uses of Structure in C
C structures are used for the following:
1. The structure can be used to define the custom data types that can be used to create some
complex data types such as dates, time, complex numbers, etc. which are not present in the
language.
2. It can also be used in data organization where a large amount of data can be stored in
different fields.
3. Structures are used to create data structures such as trees, linked lists, etc.
4. They can also be used for returning multiple values from a function.
Limitations of C Structures
In C language, structures provide a method for packing together data of different types. A
Structure is a helpful tool to handle a group of logically related data items. However, C
structures also have some limitations.
Higher Memory Consumption: It is due to structure padding.
No Data Hiding: C Structures do not permit data hiding. Structure members can be accessed
by any function, anywhere in the scope of the structure.
Functions inside Structure: C structures do not permit functions inside the structure so we
cannot provide the associated functions.
Static Members: C Structure cannot have static members inside its body.
Construction creation in Structure: Structures in C cannot have a constructor inside
Structures
C - Unions
A union is a special data type available in C that allows to store different data types in
the same memory location. You can define a union with many members, but only one
member can contain a value at any given time. Unions provide an efficient way of
using the same memory location for multiple-purpose.
Defining a Union
To define a union, you must use the union statement in the same way as you did while
defining a structure. The union statement defines a new data type with more than one
member for your program. The format of the union statement is as follows −
union [union tag] {
member definition;
member definition;
...
member definition;
} [one or more union variables];
The union tag is optional and each member definition is a normal variable definition,
such as int i; or float f; or any other valid variable definition. At the end of the union's
definition, before the final semicolon, you can specify one or more union variables but
it is optional. Here is the way you would define a union type named Data having three
members i, f, and str −
union Data {
int i;
float f;
char str[20];
} data;
Now, a variable of Data type can store an integer, a floating-point number, or a string
of characters. It means a single variable, i.e., same memory location, can be used to
store multiple types of data. You can use any built-in or user defined data types inside
a union based on your requirement.
The memory occupied by a union will be large enough to hold the largest member of
the union. For example, in the above example, Data type will occupy 20 bytes of
memory space because this is the maximum space which can be occupied by a
character string. The following example displays the total memory size occupied by
the above union −
Live Demo
#include <stdio.h>
#include <string.h>
union Data {
int i;
float f;
char str[20];
};
int main( ) {
union Data data;
printf( "Memory size occupied by data : %d\n", sizeof(data));
return 0;
}
When the above code is compiled and executed, it produces the following result −
Memory size occupied by data : 20
It uses stack for managing the static It uses heap for managing the dynamic
3
allocation of memory allocation of memory
In this allocated memory remains from In this allocated memory can be released at
10
start to end of the program. any time during the program.
#include <stdio.h>
#include <stdlib.h>
int main()
int* ptr;
int n, i;
if (ptr == NULL) {
exit(0);
else {
ptr[i] = i + 1;
}
// Print the elements of the array
return 0;
Output
Enter number of elements: 5
Memory successfully allocated using malloc.
The elements of the array are: 1, 2, 3, 4, 5,
C calloc() method
1. “calloc” or “contiguous allocation” method in C is used to dynamically allocate the
specified number of blocks of memory of the specified type. it is very much similar to
malloc() but has two different points and these are:
2. It initializes each block with a default value ‘0’.
3. It has two parameters or arguments as compare to malloc().
Syntax of calloc() in C
ptr = (cast-type*)calloc(n, element-size);
here, n is the no. of elements and element-size is the size of each element.
For Example:
ptr = (float*) calloc(25, sizeof(float));
This statement allocates contiguous space in memory for 25 elements each with the size of the
float.
ADVERTISING
If space is insufficient, allocation fails and returns a NULL pointer.
Example of calloc() in C
C
#include <stdio.h>
#include <stdlib.h>
int main()
int* ptr;
int n, i;
n = 5;
printf("Enter number of elements: %d\n", n);
if (ptr == NULL) {
exit(0);
else {
ptr[i] = i + 1;
}
// Print the elements of the array
return 0;
Output
Enter number of elements: 5
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5,
C free() method
“free” method in C is used to dynamically de-allocate the memory. The memory allocated
using functions malloc() and calloc() is not de-allocated on their own. Hence the free() method
is used, whenever the dynamic memory allocation takes place. It helps to reduce wastage of
memory by freeing it.
Syntax of free() in C
free(ptr);
Example of free() in C
C
#include <stdio.h>
#include <stdlib.h>
int main()
int n, i;
// Get the number of elements for the array
n = 5;
exit(0);
else {
free(ptr);
free(ptr1);
return 0;
Output
Enter number of elements: 5
Memory successfully allocated using malloc.
Malloc Memory successfully freed.
C realloc() method
“realloc” or “re-allocation” method in C is used to dynamically change the memory allocation
of a previously allocated memory. In other words, if the memory previously allocated with the
help of malloc or calloc is insufficient, realloc can be used to dynamically re-allocate memory.
re-allocation of memory maintains the already present value and new blocks will be initialized
with the default garbage value.
Syntax of realloc() in C
ptr = realloc(ptr, newSize);
where ptr is reallocated with new size 'newSize'.
#include <stdio.h>
#include <stdlib.h>
int main()
int* ptr;
int n, i;
n = 5;
if (ptr == NULL) {
exit(0);
else {
ptr[i] = i + 1;
n = 10;
ptr[i] = i + 1;
free(ptr);
return 0;
Output
Enter number of elements: 5
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5,
#include <stdio.h>
#include <stdlib.h>
int main()
int index = 0, i = 0, n,
int ans;
marks = (int*)malloc(sizeof(
// malloc or not?
if (marks == NULL) {
else {
"using malloc\n");
do {
scanf("%d", &ans);
if (ans == 1) {
index++;
marks = (int*)realloc(
marks,
(index + 1)
* sizeof(
if (marks == NULL) {
printf("memory cannot be allocated");
else {
printf(
///beginning address of
///allocated memory
marks[i]);
free(marks);
return 0;
}
Output:
C++ Classes/Objects
C++ is an object-oriented programming language.
Everything in C++ is associated with classes and objects, along with its attributes and methods. For example:
in real life, a car is an object. The car has attributes, such as weight and color, and methods, such as drive
and brake.
Attributes and methods are basically variables and functions that belongs to the class. These are often
referred to as "class members".
A class is a user-defined data type that we can use in our program, and it works as an object constructor, or a
"blueprint" for creating objects.
Create a Class
To create a class, use the class keyword:
Example
Create a class called "MyClass":
Create an Object
In C++, an object is created from a class. We have already created the class named MyClass, so now we can
use this to create objects.
To create an object of MyClass, specify the class name, followed by the object name.
To access the class attributes (myNum and myString), use the dot syntax (.) on the object:
Example
Create an object called "myObj" and access the attributes:
int main() {
MyClass myObj; // Create an object of MyClass
Multiple Objects
You can create multiple objects of one class:
Example
// Create a Car class with some attributes
class Car {
public:
string brand;
string model;
int year;
};
int main() {
// Create an object of Car
Car carObj1;
carObj1.brand = "BMW";
carObj1.model = "X5";
carObj1.year = 1999;
Constructors in C++
Constructor in C++ is a special method that is invoked automatically at the time of object
creation. It is used to initialize the data members of new objects generally. The constructor in C++
has the same name as the class or structure. It constructs the values i.e. provides data for the object
which is why it is known as constructor.
• Constructor is a member function of a class, whose name is same as the class name.
• Constructor is a special type of member function that is used to initialize the data members for
an object of a class automatically, when an object of the same class is created.
• Constructor is invoked at the time of object creation. It constructs the values i.e. provides data
for the object that is why it is known as constructor.
• Constructor do not return value, hence they do not have a return type.
Courses
Practice
Jobs
An array in C/C++ or be it in any programming language is a collection of similar data items
stored at contiguous memory locations and elements can be accessed randomly using indices of
an array. They can be used to store the collection of primitive data types such as int, float,
double, char, etc of any particular type. To add to it, an array in C/C++ can store derived data
types such as structures, pointers, etc. Given below is the picture representation of an array.
Example:
Let’s consider an example of taking random integers from the user.
Array
Array of Objects
When a class is defined, only the specification for the object is defined; no memory or storage is
allocated. To use the data and access functions defined in the class, you need to create objects.
Syntax:
ClassName ObjectName[number of objects];
The Array of Objects stores objects. An array of a class type is also known as an array of
objects.
Object as an argument in C++ with example
Learn: How to pass an object within the class member function as an argument in C++
programming language?
As we know that, we can pass any type of arguments within the member function and there are
any numbers of arguments.
In C++ programming language, we can also pass an object as an argument within the member
function of class.
This is useful, when we want to initialize all data members of an object with another object, we
can pass objects and assign the values of supplied object to the current object. For complex or
large projects, we need to use objects as an argument or parameter.
#include <iostream>
using namespace std;
class Demo {
private:
int a;
public:
void set(int x)
{
a = x;
}
void print()
{
cout << "Value of A : " << a << endl;
}
};
int main()
{
//object declarations
Demo d1;
Demo d2;
Demo d3;
return 0;
}
Output
Value of A : 10
Value of A : 20
Value of A : 30
Above example demonstrate the use of object as a parameter. We are passing d1 and d2 objects
as arguments to the sum member function and adding the value of data members a of both
objects and assigning to the current object’s (that will call the function, which is d3) data
member a.
References in C++
Read
Discuss(170+)
Courses
Practice
Video
When a variable is declared as a reference, it becomes an alternative name for an existing
variable. A variable can be declared as a reference by putting ‘&’ in the declaration.
Also, we can define a reference variable as a type of variable that can act as a reference to
another variable. ‘&’ is used for signifying the address of a variable or any memory. Variables
associated with reference variables can be accessed either by its name or by the reference
variable associated with it.
Prerequisite: Pointers in C++
Syntax:
data_type &ref = variable;
Example:
C++
// use of references
#include <iostream>
int main()
{
int x = 10;
// ref is a reference to x.
int& ref = x;
ref = 20;
x = 30;
return 0;
Output:
x = 20
ref = 30
Courses
Practice
Jobs
A default argument is a value provided in a function declaration that is automatically assigned
by the compiler if the calling function doesn’t provide a value for the argument. In case any
value is passed, the default value is overridden.
1) The following is a simple C++ example to demonstrate the use of default arguments. Here,
we don’t have to write 3 sum functions; only one function works by using the default values for
3rd and 4th arguments.
CPP
#include <iostream>
return (x + y + z + w);
// Driver Code
int main()
// Statement 1
// Statement 3
return 0;
Output
25
50
80
Destructors in C++
Read
Courses
Practice
Video
Jobs
What is a destructor?
Destructor is an instance member function that is invoked automatically whenever an object is
going to be destroyed. Meaning, a destructor is the last function that is going to be called before
an object is destroyed.
A destructor is also a special member function like a constructor. Destructor destroys the
class objects created by the constructor.
Destructor has the same name as their class name preceded by a tilde (~) symbol.
It is not possible to define more than one destructor.
The destructor is only one way to destroy the object created by the constructor. Hence
destructor can-not be overloaded.
Destructor neither requires any argument nor returns any value.
It is automatically called when an object goes out of scope.
Destructor release memory space occupied by the objects created by the constructor.
In destructor, objects are destroyed in the reverse of an object creation.
The thing is to be noted here if the object is created by using new or the constructor uses new to
allocate memory that resides in the heap memory or the free store, the destructor should use
delete to free the memory.
Courses
Practice
Video
Jobs
Object-oriented programming – As the name suggests uses objects in programming. Object-
oriented programming aims to implement real-world entities like inheritance, hiding,
polymorphism, etc. in programming. The main aim of OOP is to bind together the data and the
functions that operate on them so that no other part of the code can access this data except that
function.
There are some basic concepts that act as the building blocks of OOPs i.e.
1. Class
2. Objects
3. Encapsulation
4. Abstraction
5. Polymorphism
6. Inheritance
7. Dynamic Binding
8. Message Passing
Characteristics of an Object-Oriented Programming Language
Class
The building block of C++ that leads to Object-Oriented programming is a Class. It is a user-
defined data type, which holds its own data members and member functions, which can be
accessed and used by creating an instance of that class. A class is like a blueprint for an object.
For Example: Consider the Class of Cars. There may be many cars with different names and
brands but all of them will share some common properties like all of them will have 4 wheels,
Speed Limit, Mileage range, etc. So here, the Car is the class, and wheels, speed limits, and
mileage are their properties.
A Class is a user-defined data type that has data members and member functions.
Data members are the data variables and member functions are the functions used to
manipulate these variables together these data members and member functions define the
properties and behavior of the objects in a Class.
In the above example of class Car, the data member will be speed limit, mileage, etc and
member functions can apply brakes, increase speed, etc.
We can say that a Class in C++ is a blueprint representing a group of objects which shares some
common properties and behaviors.
Object
An Object is an identifiable entity with some characteristics and behavior. An Object is an
instance of a Class. When a class is defined, no memory is allocated but when it is instantiated
(i.e. an object is created) memory is allocated.
C++
#include <iostream>
class person {
char name[20];
int id;
public:
void getdetails() {}
};
int main()
return 0;
}
Objects take up space in memory and have an associated address like a record in pascal or
structure or union. When a program is executed the objects interact by sending messages to one
another. Each object contains data and code to manipulate the data. Objects can interact without
having to know details of each other’s data or code, it is sufficient to know the type of message
accepted and the type of response returned by the objects.
To know more about C++ Objects and Classes, refer to this article – C++ Classes and Objects
Encapsulation
In normal terms, Encapsulation is defined as wrapping up data and information under a single
unit. In Object-Oriented Programming, Encapsulation is defined as binding together the data and
the functions that manipulate them. Consider a real-life example of encapsulation, in a company,
there are different sections like the accounts section, finance section, sales section, etc. The
finance section handles all the financial transactions and keeps records of all the data related to
finance. Similarly, the sales section handles all the sales-related activities and keeps records of
all the sales. Now there may arise a situation when for some reason an official from the finance
section needs all the data about sales in a particular month. In this case, he is not allowed to
directly access the data of the sales section. He will first have to contact some other officer in
the sales section and then request him to give the particular data. This is what encapsulation is.
Here the data of the sales section and the employees that can manipulate them are wrapped
under a single name “sales section”.
Encapsulation in C++
Encapsulation also leads to data abstraction or data hiding. Using encapsulation also hides the
data. In the above example, the data of any of the sections like sales, finance, or accounts are
hidden from any other section.
To know more about encapsulation, refer to this article – Encapsulation in C++
Abstraction
Data abstraction is one of the most essential and important features of object-oriented
programming in C++. Abstraction means displaying only essential information and hiding the
details. Data abstraction refers to providing only essential information about the data to the
outside world, hiding the background details or implementation. Consider a real-life example of
a man driving a car. The man only knows that pressing the accelerator will increase the speed of
the car or applying brakes will stop the car but he does not know how on pressing the accelerator
the speed is actually increasing, he does not know about the inner mechanism of the car or the
implementation of an accelerator, brakes, etc. in the car. This is what abstraction is.
Abstraction using Classes: We can implement Abstraction in C++ using classes. The class
helps us to group data members and member functions using available access specifiers. A
Class can decide which data member will be visible to the outside world and which is not.
Abstraction in Header files: One more type of abstraction in C++ can be header files. For
example, consider the pow() method present in math.h header file. Whenever we need to
calculate the power of a number, we simply call the function pow() present in the math.h
header file and pass the numbers as arguments without knowing the underlying algorithm
according to which the function is actually calculating the power of numbers.
To know more about C++ abstraction, refer to this article – Abstraction in C++
Polymorphism
The word polymorphism means having many forms. In simple words, we can define
polymorphism as the ability of a message to be displayed in more than one form. A person at the
same time can have different characteristics. A man at the same time is a father, a husband, and
an employee. So the same person possesses different behavior in different situations. This is
called polymorphism. An operation may exhibit different behaviors in different instances. The
behavior depends upon the types of data used in the operation. C++ supports operator
overloading and function overloading.
Operator Overloading: The process of making an operator exhibit different behaviors in
different instances is known as operator overloading.
Function Overloading: Function overloading is using a single function name to perform
different types of tasks. Polymorphism is extensively used in implementing inheritance.
Example: Suppose we have to write a function to add some integers, sometimes there are 2
integers, and sometimes there are 3 integers. We can write the Addition Method with the same
name having different parameters, the concerned method will be called according to
parameters.
Polymorphism in C++
#include <iostream>
public:
print();
};
public:
<< endl;
};
int main()
{
GFG geeksforgeeks; // Creating GFG's object
return 0;
Output
Printing the Base class Content
Printing the Base class Content
As we can see, the print() function of the parent class is called even from the derived class
object. To resolve this we use virtual functions.
Message Passing
Objects communicate with one another by sending and receiving information. A message for an
object is a request for the execution of a procedure and therefore will invoke a function in the
receiving object that generates the desired results. Message passing involves specifying the
name of the object, the name of the function, and the information to be sent.
A virtual function (also known as virtual methods) is a member function that is declared within a
base class and is re-defined (overridden) by a derived class. When you refer to a derived class
object using a pointer or a reference to the base class, you can call a virtual function for that
object and execute the derived class’s version of the method.
Virtual functions ensure that the correct function is called for an object, regardless of the
type of reference (or pointer) used for the function call.
They are mainly used to achieve Runtime polymorphism.
Functions are declared with a virtual keyword in a base class.
The resolving of a function call is done at runtime.
Rules for Virtual Functions
The rules for the virtual functions in C++ are as follows:
1. Virtual functions cannot be static.
2. A virtual function can be a friend function of another class.
3. Virtual functions should be accessed using a pointer or reference of base class type to
achieve runtime polymorphism.
4. The prototype of virtual functions should be the same in the base as well as the derived class.
5. They are always defined in the base class and overridden in a derived class. It is not
mandatory for the derived class to override (or re-define the virtual function), in that case,
the base class version of the function is used.
6. A class may have a virtual destructor but it cannot have a virtual constructor.
Compile time (early binding) VS runtime (late binding) behavior of Virtual
Functions
Consider the following simple program showing the runtime behavior of virtual functions.
C++
#include <iostream>
class base {
public:
};
public:
void print() { cout << "print derived class\n"; }
};
int main()
base* bptr;
derived d;
bptr = &d;
bptr->print();
bptr->show();
return 0;
Output
print derived class
show base class
Virtual base classes are used in virtual inheritance in a way of preventing multiple “instances” of
a given class appearing in an inheritance hierarchy when using multiple inheritances.
Need for Virtual Base Classes: Consider the situation where we have one class A . This
class A is inherited by two other classes B and C. Both these class are inherited into another in a
new class D as shown in figure below.
As we can see from the figure that data members/function of class A are inherited twice to
class D. One through class B and second through class C. When any data / function member of
class A is accessed by an object of class D, ambiguity arises as to which data/function member
would be called? One inherited through B or the other inherited through C. This confuses
compiler and it displays error.