0% found this document useful (0 votes)
52 views29 pages

Unit 3

Uploaded by

notalexrohith
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
52 views29 pages

Unit 3

Uploaded by

notalexrohith
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

UNIT III-POINTERS

Pointers: Declaring and defining pointers, Pointer operators, Pointer expression;


Pointer Assignment, Pointer Conversions, Pointer arithmetic, Pointer Comparisons;
Pointers and Arrays: Array of pointers; Multiple Indirection; Pointers to function;
Problems with Pointers; Parameter passing: Pass by value, Pass by reference.
Pointers
Pointers in C are easy and fun to learn. Some C programming tasks are performed
more easily with pointers, and other tasks, such as dynamic memory allocation,
cannot be performed without using pointers. So it becomes necessary to learn
pointers to become a perfect C programmer. Let's start learning them in simple and
easy steps.
As you know, every variable is a memory location and every memory location has its
address defined which can be accessed using ampersand (&) operator, which denotes
an address in memory. Consider the following example, which prints the address of
the variables defined –
#include <stdio.h>
int main ()
{
int var1; char var2[10];
printf("Address of var1 variable: %x\n", &var1 );
printf("Address of var2 variable: %x\n", &var2 );
return 0;
}
When the above code is compiled and executed, it produces the following result −
Address of var1 variable: bff5a400
Address of var2 variable: bff5a3f6
What are Pointers?
A pointer is a variable that stores the address of another variable. Unlike other
variables that hold values of a certain type, pointer holds the address of a variable.
For example, an integer variable holds (or you can say stores) an integer value,
however an integer pointer holds the address of a integer variable.

Declaring a Pointer
Like variables, pointers in C programming have to be declared before they can be
used in your program. Pointers can be named anything you want as long as they
obey C’s naming rules. A pointer declaration has the following form.
data_type * pointer_variable_name;
Here,

St. Joseph’s College of Engineering Page 1


data_type is the pointer’s base type of C’s variable types and indicates the type of the
variable that the pointer points to.
The asterisk (* the same asterisk used for multiplication) which is indirection
operator, declares a pointer.
Take a look at some of the valid pointer declarations −
int *ip; /* pointer to an integer */
double *dp; /* pointer to a double */
float *fp; /* pointer to a float */
char *ch /* pointer to a character */
The actual data type of the value of all pointers, whether integer, float, character, or
otherwise, is the same, a long hexadecimal number that represents a memory
address. The only difference between pointers of different data types is the data type
of the variable or constant that the pointer points to.
Initialize a pointer
After declaring a pointer, we initialize it like standard variables with a variable
address. If pointers in C programming are not uninitialized and used in the program,
the results are unpredictable and potentially disastrous.
To get the address of a variable, we use the ampersand (&)operator, placed before
the name of a variable whose address we need. Pointer initialization is done with the
following syntax.
Pointer Syntax
Datatype variable;
Datatype *ptr = &variable;
#include<stdio.h>
int main ()
{
int a;
int *ptr;
ptr = &a;
a = 10;
printf ("\n %p %p", &a, ptr);
printf ("\n %d %d", a, *ptr);
*ptr = 20;
printf ("\n %u %u", &a, ptr);
printf ("\n %d %d", a, *ptr);
return 0;
}
Output:

St. Joseph’s College of Engineering Page 2


 On any variable when we are applying address-of operator (&) then always it will
collect the base address only i.e. the starting cell location. On address when we are
applying indirection operator (*) then it returns the value of that address.
 In the above program, ptr holds the address of a (&a) that’s why ptr and & value
are the same. *ptr always returns an object i.e. value that’s why ‘*ptr’ and a value
are the same.
 In implementation when we are printing the address of the variable then go for %x,
%p, %u. %lu and %lp format specifiers. %x, %p, %lp will print the address in
hexadecimal format, and %u, %lu will print the address in decimal format.
 Note: For printing the address we cannot use the %d format specifier because the
physical address will be there in hexadecimal format from the range of 0*0000 to
0*ffff, in decimal format 0 to 65535 so this range will not be supported by %d. There
is no –ve representation is available in physical address but %d will print –ve data
also,
Advantage of pointer
 The Pointer reduces the code and improves the performance of the application.
 We can return multiple values from a function using the pointer.
 It makes you able to access any memory location in the computer’s memory.
 Pointers are more efficient in handling arrays and data tables.
 The use of pointer arrays to character strings results in saving of data storage
space in memory.
 Pointers allow C to support dynamic memory management.
 Pointers provide an efficient tool for manipulating dynamic data structures
such as structures , linked lists , queues , stacks and trees.
 Pointers reduce length and complexity of programs.
 They increase the execution speed and thus reduce the program execution time.
Usage of pointer:
 There are many applications of pointers in the C language.
 Dynamic memory allocation: In the C language, we can dynamically allocate
memory using malloc() and calloc() functions where the pointer is used.
 Arrays, Functions, and Structures: The Pointers in C language are widely used in
arrays, functions, and structures. It reduces the code and improves the
performance.
Pointers Operators
There are two pointer operators :
1. value at address operator ( * )
2. address of operator ( & )

St. Joseph’s College of Engineering Page 3


Value at address operator ( * )
The * is a unary operator. It gives the value stored at a particular address. The ‘value
at address’ operator is also called ‘indirection’ operator.
q = *m;
if m contains the memory address of the variable count, then preceding assignment
statement can places the value of count into q.
Address of operator ( & )
The & is a unary operator that returns the memory address of its operand.
m = & count;
The preceding assignment statement can be “The memory address of the variable
count is places into m”.
\* Pointer to initialize and print the value and address of variable. *\
# include < stdio.h >
int main( )
{
int a = 25 ;
int *b ;
b = &a ;
printf("\n Address of a = %u ", & a) ;
printf("\n Address of a = %u ", b) ;
printf("\n Address of b = %u ", & b) ;
printf("\n Value of b = %u ", b) ;
printf("\n Value of a = %d ", a) ;
printf("\n Value of a = %d ", *( &a ) )) ;
printf("\n Value of a = %d ", *b) ;
return ( 0 );
}
Output of the program :
Address of a = 12345
Address of a = 12345
Address of b = 12345
Value of b = 12345
Value of a = 5
Value of a = 5
Value of a = 5
How to Use Pointers?
There are a few important operations, which we will do with the help of pointers very
frequently.
(a) We define a pointer variable,
(b) assign the address of a variable to a pointer and
(c) Finally access the value at the address available in the pointer variable.

St. Joseph’s College of Engineering Page 4


This is done by using unary operator * that returns the value of the variable located at
the address specified by its operand. The following example makes use of these
operations –
#include <stdio.h>
int main ()
{
int var = 20; /* actual variable declaration */
int *ip;/* pointer variable declaration */
ip = &var; /* store address of var in pointer variable*/ printf("Address of var
variable: %x\n", &var );
/* address stored in pointer variable */ printf("Address stored in ip variable: %x\n",
ip ); /*access the value using the pointer */
printf("Value of *ip variable: %d\n", *ip );
return 0;
}
When the above code is compiled and executed, it produces the following result −
Address of var variable: bffd8b3c
Address stored in ip variable: bffd8b3c
Value of *ip variable: 20

Meaning of following simple pointer declaration and definition:


int a=5; int* ptr;
ptr=&a;
Explanation:
About variable ―a :
1. Name of variable: a
2. Value of variable which it keeps: 5
3. Address where it has stored in memory: 1025 (assume)
About variable ―ptr :
4. Name of pointer variable: ptr
5. Value of variable which it keeps: 1025
6. Address where it has stored in memory: 5000 (assume)

Note: A variable where it will be stored in memory is decided by operating system.


We cannot guess at which location a particular variable will be stored in memory.
Pointers are built on three underlying concepts which are illustrated below:-

St. Joseph’s College of Engineering Page 5


 Memory addresses within a computer are referred to as pointer constants. We
cannot change them. We can only use them to store data values. They are like
house numbers.
 We cannot save the value of a memory address directly. We can only obtain the
value through the variable stored there using the address operator (&). The
value thus obtained is known as pointer value.
 The pointer value (i.e. the address of a variable) may change from one run of
the program to another. Once we have a pointer value, it can be stored into
another variable. The variable that contains a pointer value is called a pointer
variable.

Types of Pointers
There are majorly four types of pointers, they are:
Null Pointer
Void Pointer
Wild Pointer
Dangling Pointer
Null Pointer
We can create a null pointer by assigning null value during the pointer declaration.
This method is useful when you do not have any address assigned to the pointer. A
null pointer always contains value 0.
Following program illustrates the use of a null pointer:
#include <stdio.h>
int main()
{
int *p = NULL; //null pointer
printf(“The value inside variable p is:\n%x”,p);
return 0;
}
Output:
The value inside variable p is:
0
Void Pointer

St. Joseph’s College of Engineering Page 6


In C programming, a void pointer is also called as a generic pointer. It does not have
any standard data type. A void pointer is created by using the keyword void. It can
be used to store an address of any variable.
Following program illustrates the use of a void pointer:
#include <stdio.h>
int main()
{
void *p = NULL; //void pointer
printf("The size of pointer is:%d\n",sizeof(p));
return 0;
}
Output:
The size of pointer is:4
Wild pointer
A pointer is said to be a wild pointer if it is not being initialized to anything. These
types of C pointers are not efficient because they may point to some unknown
memory location which may cause problems in our program and it may lead to
crashing of the program. One should always be careful while working with wild
pointers.
Following program illustrates the use of wild pointer:
#include <stdio.h>
int main()
{
int *p; //wild pointer
printf("\n%d",*p);
return 0;
}
Output:
timeout: the monitored command dumped core
sh: line 1: 95298 Segmentation fault timeout 10s main
Dangling Pointer
Suppose there is a pointer p pointing at a variable at memory 1004. If you deallocate
this memory, then this p is called a dangling pointer. You can deallocate a memory
using a free() function.
Example:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *ptr=(int *)malloc(sizeof(int));
int a=5;
ptr=&a;
free(ptr);

St. Joseph’s College of Engineering Page 7


//now this ptr is known as dangling pointer.
printf(“After deallocating its memory *ptr=%d”,*ptr);
return 0;
}
Pointer Expressions
Like other variables pointer variables can be used in expressions. For example if p1
and p2 are properly declared and initialized pointers, then the following statements
are valid.
y=*p1**p2;
sum=sum+*p1;
z= 5* - *p2/p1;
*p2= *p2 + 10;
Pointer Assignment
Pointer assignment between two pointers makes them point to the same pointer. So
the assignment y = x; makes y point to the same pointer as x. Pointer assignment does
not touch the pointers. It just changes one pointer to have the same reference as another
pointer. After pointer assignment, the two pointers are said to be "sharing" the pointer.
Pointer Arithmetic
The Pointers variables are used to store the address of another variable. The address
is nothing but the memory location assigned to the variable. That means the pointer
doesn’t store any value, it stores the address. Hence, there are only a few operations
that are allowed to perform on Pointers. The operations are slightly different from the
ones that we generally use for mathematical calculations. The operations are as
follows:
 Increment/Decrement of a Pointer
 Addition of integer to a pointer
 Subtraction of integer to a pointer
 Subtracting two pointers of the same type
Increment:
When a pointer is incremented, it actually increments by the number equal to the size
of the data type for which it is a pointer. For Example, If the pointer is of type integer
and if the pointer stores address 1000 and if the pointer is incremented, then it will
increment by 2(size of an int), and the new address that the pointer will point to 1002.
While if the pointer is of type float and if it stores the address 1000 and if the pointer
is incremented then it will increment by 4(size of a float) and the new address will be
1004.
Decrement:
It is just the opposite of the Increment operation. When a pointer is decremented, it
actually decrements by the number equal to the size of the data type for which it is a
pointer. For Example, If the pointer is of type integer and if the pointer stores the
address 1000 and if the pointer is decremented, then it will decrement by 2(size of an
int), and the new address that the pointer will point to is 998. While if the pointer is of

St. Joseph’s College of Engineering Page 8


type float and if it stores the address 1000 and if the pointer is decremented then it will
decrement by 4(size of a float) and the new address will be 996.
#include <stdio.h>
int main ()
{
// Integer variable
int a = 10, b=20;
// Pointer to an integer
int *ptr1, *ptr2;
// Pointer stores the address of variable a
ptr1 = &a;
ptr2 = &b;
printf ("Pointer ptr1 before Increment: ");
printf ("%p \n", ptr1);
// Incrementing pointer ptr1;
ptr1++;
printf ("Pointer ptr1 after Increment: ");
printf ("%p \n\n", ptr1);
printf ("Pointer ptr2 before Decrement: ");
printf ("%p \n", ptr2);
// Decrementing pointer ptr2;
ptr2--;
printf ("Pointer ptr2 after Decrement: ");
printf ("%p \n\n", ptr2);
return 0;
}
Output:

Addition:
In C Programming Language, When a pointer is added with a value, then the value is
first multiplied by the size of the data type and then added to the pointer.
Subtraction:
In C Programming Language, When a pointer is subtracted with a value, then the
value is first multiplied by the size of the data type and then subtracted from the
pointer.
#include <stdio.h>
int main()
{

St. Joseph’s College of Engineering Page 9


// Integer variable
int a = 10;
// Pointer to an integer
int *ptr1, *ptr2;
// Pointer stores the address of variable a
ptr1 = &a;
ptr2 = &a;
printf("Pointer ptr1 before Addition: ");
printf("%p \n", ptr1);
// Addition of 2 to pointer ptr1
ptr1 = ptr1 + 2;
printf("Pointer ptr1 after Addition: ");
printf("%p \n", ptr1);
printf("Pointer ptr2 before Subtraction : ");
printf("%p \n", ptr2);
// Subtraction of 2 from pointer ptr2
ptr2 = ptr2 + 2;
printf("Pointer ptr1 after Subtraction : ");
printf("%p \n", ptr2);
return 0;
}

Output:

Addition and Subtraction of two Pointers


#include<stdio.h>
int main ()
{
int a = 30, b = 10, *p1, *p2, sum;
p1 = &a;
p2 = &b;
sum = *p1 + *p2;
printf ("Addition of two numbers = %d\n", sum);
sum = *p1 - *p2;
printf ("Subtraction of two numbers = %d\n", sum);
return 0;
}
Pointers Rule:
Rule 1:

St. Joseph’s College of Engineering Page 10


Address + Number // Address (Next Address)
Address – Number // Address (Pre-Address)
Address++ // Address (Next Address)
Address– // Address (Pre-Address)
++Address // Address (Next Address)
–Address // Address (Pre-Address)
Rule 2:
Address-Address //Number (No. of elements) //size difference / size of (datatype)
Example:
int*p1=(int*)100
int*p2=(int*)200
p2-p1=50
200-100=100 / size of (int)
Rule 3:
Address + Address = illegal
Address * Address = illegal
Address / Address = illegal
Address % Address = illegal
Rule 4:
We can’t perform a bitwise operation between 2 pointers like
Address & Address = illegal
Address | Address = illegal
Address ^ Address = illegal
~Address = illegal
Rule 5:
We can use relational operator and conditional operator (<,>, <=,>=, ==, !=, ?:)
between 2 pointers
Address > Address = T/F
Address >= Address = T/F
Rule 6:
We can find the size of a pointer using the sizeof operator.
Pointer Comparisons
In C language pointers can be compared if the two pointers are pointing to the same
array. All relational operators can be used for pointer comparison, but a pointer cannot
Multiplied or Divided.
#include <stdio.h>
int main() {
int *p2;
int *p1;
p2 = (int *)300;
p1 = (int *)200;
if(p1 > p2)
{

St. Joseph’s College of Engineering Page 11


printf("P1 is greater than p2");
}
else
{
printf("P2 is greater than p1");
}
return(0);
}
Output
P2 is greater than p1
Some Key points about pointer comparison −
 p1<=p2 and p1>=p2 both yield true and p1<p2 and p1>p2 both yield false, if two
pointers p1 and p2 of the same type point to the same object or function, or both
point one past the end of the same array, or are both null.
 p1<p2, p1>p2, p1<=p2 and p1>=p2 are unspecified, if two pointers p1 and p2 of
the same type point to different objects that are not members of the same object or
elements of the same array or to different functions, or if only one of them is null.
 If two pointers point to non-static data members of the same object, or to sub objects
or array elements of such members, with same access control then the result is
specified.
 The result is unspecified, if two pointers point to non-static data members of the
same object with different access control.

Arrays and Pointers

Arrays are closely related to pointers in C programming but the important difference
between them is that, a pointer variable takes different addresses as value whereas, in
case of array it is fixed.
#include <stdio.h>
int main()
{
char charArr[4]; int i;
for(i = 0; i < 4; ++i)
{

St. Joseph’s College of Engineering Page 12


printf("Address of charArr[%d] = %u\n", i, &charArr[i]);
}
return 0;
}
When you run the program, the output will be:
Address of charArr[0] = 28ff44 Address of charArr[1] = 28ff45 Address of charArr[2]
= 28ff46 Address of charArr[3] = 28ff47
Note: You may get different address of an array.
Notice, that there is an equal difference (difference of 1 byte) between any two
consecutive elements of array charArr.
But, since pointers just point at the location of another variable, it can store any
address.
Relation between Arrays and Pointers
Consider an array:

 int arr[4];
 In C programming, name of the array always points to address of the first
element of an array.
 In the above example, arr and &arr[0] points to the address of the first element.
 &arr[0] is equivalent to arr .Since, the addresses of both are the same, the values
of arr and &arr[0] are also the same.
 arr[0] is equivalent to *arr (value of an address of the pointer)

Similarly,
 &arr[1] is equivalent to (arr + 1) AND, arr[1] is equivalent to *(arr + 1).
 arr[2] is equivalent to (arr + 2) AND, arr[2] is equivalent to *(arr + 2).
 &arr[3] is equivalent to (arr + 3) AND, arr[3] is equivalent to *(arr + 3).
 &arr[i] is equivalent to (arr + i) AND, arr[i] is equivalent to *(arr + i).
 In C, you can declare an array and can use pointer to alter the data of an array.
Example: Program to find the sum of six numbers with arrays and pointers
#include <stdio.h> int main()
{
int i, classes[6],sum = 0;
printf("Enter 6 numbers:\n");
for(i = 0; i < 6; ++i)
{
// (classes + i) is equivalent to &classes[i]
scanf("%d",(classes + i));
// *(classes + i) is equivalent to classes[i]

St. Joseph’s College of Engineering Page 13


sum += *(classes + i);
}
printf("Sum = %d", sum); return 0;
}
Output
Enter 6 numbers:
2
3
4
5
3
4
Sum = 21
Array of pointers
 When we want to point at multiple variables or memories of the same data type in
a C program, we use an array of pointers.
 Let us assume that a total of five employees are working at a cheesecake factory.
We can store the employees’ names in the form of an array. Along with this, we
also store the names of employees working at the office, the library, and the shoe
store.
 Now, let us assume that once we read all the names of the employees randomly,
we want to sort all of the employees’ names working in the cheesecake factory.
Sorting all the employee names requires reading, swapping, and copying a lot of
data. But since we have stored all the employee names in groups/ arrays, we can
directly refer to the array of names of employees working at the cheesecake factory.
Let's create an array of 5 pointers.
int *arr[5];
Where arr[0] will hold one integer variable address, arr[1] will hold another integer
variable address and so on.
#include<stdio.h>
#define size 5
int main()
{
int *arr[size];
int a = 10, b = 20, c = 30, d = 40, e = 50, i;
arr[0] = &a;
arr[1] = &b;
arr[2] = &c;
arr[3] = &d;
arr[4] = &e;
printf("Address of a = %p\n",arr[0]);
printf("Address of b = %p\n",arr[1]);
printf("Address of c = %p\n",arr[2]);

St. Joseph’s College of Engineering Page 14


printf("Address of d = %p\n",arr[3]);
printf("Address of e = %p\n",arr[4]);
for(i = 0; i < size; i++)
printf("value stored at arr[%d] = %d\n",i,*arr[i]);
return 0;
}
Dereferencing array of pointer
 Dereference - Accessing the value stored at the pointer.
 Since each array index pointing to a variable's address, we need to use
*arr[index] to access the value stored at the particular index's address.
 arr[index] will have address
 *arr[index] will print the value.

Where arr[0] holding the address of the variable a. i.e. arr[0] = 1024
*arr[0] -> *1024 -> value stored at the memory address 1024 is 10. So, *arr[0] = 10.
Similarly, *arr[1] = 20, *arr[2] = 30 and so on.
Application of array of pointers
Assume that we are going to build an embedded system which uses a different kind
of sensors to measure the temperature.
In this case, we can use an array of pointers to hold the memory address of each
sensor so that it will be very easy to manipulate the sensor status.
Example
sensor[0] will hold the address of the 1st sensor.
sensor[1] will hold the address of the second sensor and so on.
Since it is an array, we can directly interact with the particular sensor using array
index.
we can get the temperature status of 1st sensor using sensor[0], 2nd sensor status
using sensor[1] and so on.
Pointer to pointer
We can also store the address of another pointer in c.
Example

St. Joseph’s College of Engineering Page 15


int a = 10;
int *ptr = &a;
Where, ptr is a pointer which is holding the address of variable a. If we need to hold
the address of ptr, what will be the solution? Pointer to Pointer.
Declaration of pointer to pointer (double pointer)
int a = 10;
int *ptr = &a;
int **dptr = &ptr;
We need to use ** to declare the pointer to pointer(double pointer) variable.
** declaration indicates that I am a pointer but I am not pointing to a variable rather
pointing to the address of another pointer.

Referencing and dereferencing a double pointer


i)Referencing
Assigning an address to the pointer.
ii)Dereferencing
Accessing the value stored at the pointer.
Example
#include<stdio.h>
int main()
{
int a = 10;
int *ptr = &a; //ptr references a
int **dptr = &ptr; //dptr references ptr

printf("Address of a = %p\n",&a);
printf("ptr is pointing to the address = %p\n",ptr);
printf("dptr is pointing to the address = %p\n",dptr);
printf("Value of a = %d\n",a);
printf("*ptr = %d\n",*ptr);
printf("**dptr = %d\n",**dptr);

return 0;
}
*ptr -> *1024 -> value stored at the memory 1024 is 10 ->10

St. Joseph’s College of Engineering Page 16


**dptr -> *(*2024)-> value stored at the memory address 2024 is 1024 -> *1024->value
stored at the memory address 1024 is 10 -> 10
Pointers to function
 Function pointers in C are variables that can store the memory address of functions
and can be used in a program to create a function call to functions pointed by them.
Function pointers in C need to be declared with an asterisk symbol and function
parameters (same as function they will point to) before using them in the program.
Declaration of function pointers in C includes return type and data type of different
function arguments.
 An asterisk symbol before the pointer name differentiates the function pointer from
a usual function declaration. Functions can aspect function pointer as a function
argument and later call it inside the function body. Such passed functions are
called callback function.
Declaring a Function Pointer
Now that we know that functions have a unique memory address, we can use function
pointers in C that can point to the first executable code inside a function body.

 For example, in the above figure we have a function add() to add two integer
numbers. Here, the function name points to the address of the function itself so we
are using a function pointer fptr that stores the address of beginning of the
function add(a, b) that in 1001 in this case.
 Before using a function pointer we need to declare them to tell the compiler the
type of function a pointer can point. The general syntax of a function pointer is,
Syntax of Function Pointer in C
return_type (* pointer_name) (datatype_arg_1, datatype_arg_1, ...);
 Declaring a function pointer in C is comparable to declaring a function except
that when a function pointer is declared, we prefix its name which is an
Asterisk * symbol.
 For example, if a function has the declaration
float foo (int, int);
Declaration of a function pointer in C for the function foo will be
// function pointer declaration
float (*foo_pointer) (int, int);

St. Joseph’s College of Engineering Page 17


/*assigning the address of the function (foo) to function pointer */
foo_pointer = foo;
 Here, pointer *foo_pointer is a function pointer and stores the memory address of
a function foo that takes two arguments of type int and returns a value of data
type float.
For example:
double (*p2f)(double, char)
 Here double is a return type of function, p2f is name of the function pointer and
(double, char) is an argument list of this function. Which means the first argument
of this function is of double type and the second argument is char type.
 Lets understand this with the help of an example: Here we have a function sum that
calculates the sum of two numbers and returns the sum. We have created a pointer
f2p that points to this function, we are invoking the function using this function
pointer f2p.
int sum (int num1, int num2)
{
return num1+num2;
}
int main()
{

/* The following two lines can also be written in a single


* statement like this: void (*fun_ptr)(int) = &fun;
*/
int (*f2p) (int, int);
f2p = sum;
//Calling function using function pointer
int op1 = f2p(10, 13);
//Calling function in normal way using function name
int op2 = sum(10, 13);
printf("Output1: Call using function pointer: %d",op1);
printf("\nOutput2: Call using function name: %d", op2);
return 0;
}
Output:
Output1: Call using function pointer: 23
Output2: Call using function name: 23
Some points regarding function pointer:
1. As mentioned in the comments, you can declare a function pointer and assign a
function to it in a single statement like this:
void (*fun_ptr)(int) = &fun;

St. Joseph’s College of Engineering Page 18


2. You can even remove the ampersand from this statement because a function name
alone represents the function address. This means the above statement can also be
written like this:
void (*fun_ptr)(int) = fun;
Calling a Function Through a Function Pointer in C
Calling a function using a pointer is similar to calling a function in the usual way using
the name of the function.
Suppose we declare a function and its pointer as given below
int (*pointer) (int); // function pointer declaration
int areaSquare (int); // function declaration
pointer = areaSquare;
To call the function areaSquare, we can create a function call using any of the three
ways
int length = 5;
// Different ways to call the function
// 1. using function name
int area = areaSquare(length);
// 2. using function pointer (a)
int area = (*pointer)(length);
// 3. using function pointer (b)
int area = pointer(length);
 The effect of calling functions using pointers or using their name is the same. It is
not compulsory to call the function with the indirection operator (*) as shown in
the second case but, it is good practice to use the indirection operator to clear out
that function is called using a pointer as (*pointer)() is more readable when
compared to calling function from pointers with parentheses pointer().
Example for Function Pointer in C
Now that we know the syntax of how function pointers in C are declared and used to
create a function call. Let us see an example where we are creating a function pointer
to call the function that returns the area of a rectangle.
#include<stdio.h>
int areaRectangle(int, int); // function declaration
int main() {
int length, breadth, area;
// function pointer declaration note that our pointer declaration has identical
// arguments as the function it will point to
int (*fp)(int, int);
printf("Enter length and breadth of a rectangle\n");
scanf("%d%d", &length, &breadth);
// pointing the pointer to functions memory address
fp = areaRectangle;
// calling the function using function pointer
area = (*fp)(length, breadth);

St. Joseph’s College of Engineering Page 19


printf("Area of rectangle = %d", area);
return 0;
}
// function definition
int areaRectangle(int l, int b)
{
int area_of_rectangle = l * b;
return area_of_rectangle;
}
Output
Enter length and breadth of a rectangle
59
Area of rectangle = 45
Here, we have defined a function areaRectangle() that takes two integer inputs and
return the area of the rectangle. To store the reference of the function we are using
function pointer (*fp) that has similar declaration to the function it points to. To point
the function address to the pointer we don't need to use & symbol as the function
name areaRectangle also represents functions address. To call the function we are
passing parameters inside the parenthesis ((*fp)(length, breadth)) and the return value
is stored in the variable area.
Example: Array of function pointers
Arrays are data structure that stores collection of identical data types. Like any other
data types we can create an array to store function pointers in C. Function pointers can
be access from their indexes like we access normal array values arr[i]. This way we are
creating an array of function pointers, where each array element is storing a function
pointer pointing to different function.
This approach is useful when we do not know in advance which function is called, as
shown in the example.
#include<stdio.h>
float add(int, int);
float multiply(int,int);
float divide(int,int);
float subtract(int,int);

int main() {
int a, b;
float (*operation[4])(int, int);
operation[0] = add;
operation[1] = subtract;
operation[2] = multiply;
operation[3] = divide;
printf("Enter two values ");
scanf("%d%d", &a, &b);

St. Joseph’s College of Engineering Page 20


float result = (*operation[0])(a, b);
printf("Addition (a+b) = %.1f\n", result);
result = (*operation[1])(a, b);
printf("Subtraction (a-b) = %.1f\n", result);
result = (*operation[2])(a, b);
printf("Multiplication (a*b) = %.1f\n", result);
result = (*operation[3])(a, b);
printf("Division (a/b) = %.1f\n", result);
return 0;
}

float add(int a, int b)


{
return a + b;
}

float subtract(int a, int b)


{
return a - b;
}

float multiply(int a, int b)


{
return a * b;
}

float divide(int a, int b)


{
return a / (b * 1.0);
}
Output
Enter two values 3 2
Addition (a+b) = 5.0
Subtraction (a-b) = 1.0
Multiplication (a*b) = 6.0
Division (a/b) = 1.5
Here, we have stored addresses of four functions in an array of function pointers. We
used this array to call the required function using the function pointer stored in this
array.
Problems with Pointers

 Failed to protect memory addresses (locations) - Since pointer can access direct
memory so memory cannot be protected.

St. Joseph’s College of Engineering Page 21


 Uninitialized pointers can cause of segmentation fault.
 Pointers variables are slower than normal variables.
 Pointers always required Free Memory for Dynamically Allocated Memory.

Functions Using Pointer Variables


C allows pointers to be passed in as function arguments and also return pointers from
the function. To pass pointers in the function, we simply declare the function
parameter as pointer type. When functions have their pointer type arguments, the
changes made on them inside the function persists even after program exists function
scope because the changes are made on the actual address pointed by the pointer. This
approach to pass arguments to a function is called as pass by reference because as
shown in the figure below reference of the variable is passed to the function instead of
the value stored in the address.

Extra care should be taken when function is used to return pointers because local
variables don't live outside function scope and if they are returned as pointers from
function then that pointer will point to nothing when function terminates.
For example,
#include<stdio.h>
int* increment(int a) {
int *b;
*b = a;
*b += 1; // incrementing the value
return b; // returning pointer from the function
}

int main() {
int num = 5;
int *b = increment(num);
St. Joseph’s College of Engineering Page 22
printf("Incremented value = %d", *b);
return 0;
}
 In this case, the compiler throws segmentation fault error because you are
returning a copy of a pointer to a local variable. However, that local variable is de-
allocated when the function increment finishes, so when we try to access it
afterwards compiler is not able to reference the pointer.
 Safe ways to return a pointer from a function
 Return variables are either created using the keyword static or created
dynamically at run time because such variables exist in memory beyond the scope
of the called function.
 Use arguments that are passed by their reference because such functions exist in
the calling function scope.
Example: Passing and returning values from functions using pointer in C
#include<stdio.h>
int *larger(int *, int *);
int main() {
int a = 10, b = 15;
int *greater;
// passing address of variables to function
greater = larger(&a, &b);
printf("Larger value = %d", *greater);
return 0;
}

int *larger(int *a, int *b) {


if (*a > *b) {
return a;
}
// returning address of greater value
return b;
}
Referencing and Dereferencing of Function Pointer
 Suppose we want to create a sorting function. It makes more sense to allow the
function’s caller to decide the order in which values are sorted (ascending,
descending, etc). One way is to provide a flag in the function argument to
decide what to do, but this is not flexible.
 Another way is to provide user flexibility to pass a function in our sort function.
This function can take two values as input and perform a comparison between
them. A syntax for our new function will look like.
void sort(int array[], int n, function comparison);
Parameter Passing

St. Joseph’s College of Engineering Page 23


There are different ways in which parameter data can be passed into and out of
methods and functions. Let us assume that a function B() is called from another
function A(). In this case A is called the “caller function” and B is called the
“called function or callee function”. Also, the arguments which A sends to B are
called actual arguments and the parameters of B are called formal arguments.
Terminology
 Formal Parameter : A variable and its type as they appear in the prototype
of the function or method.
 Actual Parameter : The variable or expression corresponding to a formal
parameter that appears in the function or method call in the calling
environment.
 Modes:
 IN: Passes info from caller to calle.
 OUT: Callee writes values in caller.
 IN/OUT: Caller tells callee value of variable, which may be updated by
callee.
Important methods of Parameter Passing
 Pass By Value : This method uses in-mode semantics. Changes made to formal
parameter do not get transmitted back to the caller. Any modifications to the formal
parameter variable inside the called function or method affect only the separate
storage location and will not be reflected in the actual parameter in the calling
environment. This method is also called as call by value.
// C program to illustrate call by value
#include <stdio.h>
void func(int a, int b)
{
a += b;
printf("In func, a = %d b = %d\n", a, b);
}
int main(void)
{
int x = 5, y = 7;

// Passing
parameters func(x,
y);
printf("In main, x = %d y = %d\n", x,
y); return 0;
}
Output:

St. Joseph’s College of Engineering Page 24


In func, a = 12 b = 7
In main, x = 5 y = 7
Shortcomings:
 Inefficiency in storage allocation
 For objects and arrays, the copy semantics are costly
 Pass by reference(aliasing) : This technique uses in/out-
modesemantics. Changes made to formal parameter do get
transmitted back to the caller through parameter passing. Any
changes to the formal parameter are reflected in the
 Actual parameter in the calling environment as formal parameter
receives a reference (or pointer) to the actual data. This method is also
called as <em>call by reference. This method is efficient in both time
and space.
// C program to illustrate call by reference
#include <stdio.h>
void swapnum(int* i, int* j)
{
int temp = *i;
*i = *j;
*j = temp;
}

int main(void)
{
int a = 10, b = 20;

// passing
parameters
swapnum(&a, &b);
printf("a is %d and b is %d\n", a,
b); return 0;
}
Output:
a is 20 and b is 10
Swapping of two numbers
#include <stdio.h>
int main()
{
int x, y, temp;

St. Joseph’s College of Engineering Page 25


printf("Enter the value of x andy\n");
scanf("%d%d", &x, &y);
printf("Before Swapping\nx = %d\ny = %d\n",x,y);
temp = x;
x = y;
y = temp;
printf("After Swapping\nx = %d\ny = %d\n",x,y);
return 0;
}
Output of program:

Changing the value of a variable using pass by reference


#include <stdio.h>
void swap(int*, int*); //Swap function declaration

int main()
{
int x, y;
printf("Enter the value of x and y\n");
scanf("%d%d",&x,&y);
printf("Before Swapping\nx = %d\ny = %d\n", x, y);
swap(&x, &y);
printf("After Swapping\nx = %d\ny = %d\n", x, y);
return 0;
}
//Swap function definition
void swap(int *a, int *b)
{
int t;
t = *b;
*b = *a;

St. Joseph’s College of Engineering Page 26


*a = t;
}
Output of program

Program to print the string character by character using character pointer


#include <stdio.h>
int main()
{
char *str[5]={"Hello World","Mumbai","New Delhi"};
int i,j,r;
for(i=0;i<3;i++)
{
j=0;
while(*(str[i]+j)!='\0')
{
printf("%c",*(str[i]+j));
j++;
}
printf("\n");
}
return 0;
}
Output
Hello World
Mumbai
New Delhi

Program to print the string using character pointer

#include <stdio.h>
int main()

St. Joseph’s College of Engineering Page 27


{
char *str[5]={"Hello World","Mumbai","New Delhi"}, int i;
for(i=0;i<3;i++)
{

printf("%s \n",str[i]);
}
return 0;
}
Output
Hello World
Mumbai
New Delhi
Program to sort names in alphabetical order using the concept of array of pointers
#include <stdio.h>
#include<string.h>
int main()
{
char *str[6]={"New Delhi","Gujarat","Assam","Chennai","Bangalore","Kerala"},*t;
int i,j,r;
printf("\nBefore Sorting\n");
for(i=0;i<6;i++)
{
printf("%s\n",str[i]);
}
for(i=0;i<6;i++)
{
for(j=i+1;j<5;j++)
{
r=strcmp(str[i],str[j]);
if(r>0)
{
t=str[i];
str[i]=str[j];
str[j]=t;
}
}
}
printf("\nAfter Sorting\n");
for(i=0;i<6;i++)
{

printf("%s \n",str[i]);

St. Joseph’s College of Engineering Page 28


}
return 0;
}
Output
Before Sorting
New Delhi
Gujarat
Assam
Chennai
Bangalore
Kerala

After Sorting
Assam
Bangalore
Chennai
Gujarat
Kerala
New Delhi

St. Joseph’s College of Engineering Page 29

You might also like