Unit - Iii
Unit - Iii
UNIT – III
FUNCTIONS AND POINTERS
Modular programming – Function prototype, function definition, function all, Built-in functions
(string functions, math functions) – Recursion, Binary Search using recursive functions –
Pointers – Pointer operators – Pointer arithmetic – Arrays and pointers – Array of pointers –
Parameter passing: Pass by value, Pass by reference. Simple programs based on the above
concepts must be illustrated.
MODULAR PROGRAMMING
Modular programming is a software design technique that emphasizes separating the
functionality of a program into independent, interchangeable modules, such that each contains
everything necessary to execute only one aspect of the desired functionality. There are many
advantages to using Modular Software and Programming compared to other methods.
Development can be divided: Allows development to be divided by splitting down a
program into smaller programs in order to execute a variety of tasks.
Readable programs: Helps develop programs that are much easier to read since they can
be enabled as user-defined functions.
Programming errors are easy to detect: Minimizes the risks of ending up with
programming errors and also makes it easier to spot errors, if any.
Allows re-use of codes: A program module is capable of being re-used in a program
which minimizes the development of redundant codes
Improves manageability: Having a program broken into smaller sub-programs allows
for easier management.
Collaboration: With Modular Programming, programmers can collaborate and work on
the same application.
1
FUNCTION PROTOTYPE, FUNCTION DEFINITION, FUNCTION CALL
Function A function is a group of statements that together perform a task. Every C
program has at least one function, which is main(), and all the most trivial programs can define
additional functions.
TYPES OF FUNCTIONS
There are two types of function in C programming:
Standard library functions
User-defined functions
STANDARD LIBRARY FUNCTIONS
The standard library functions are built-in functions in C programming. These functions
are defined in header files. For example,
The printf() is a standard library function to send formatted output to the screen (display
output on the screen). This function is defined in the stdio.h header file.
The sqrt() function calculates the square root of a number. The function is defined in the
math.h header file.
The strlen() function calculates the length of a given string. The function is defined in the
string.h header file.
USER-DEFINED FUNCTION
User can also create functions as per their own needs. Such functions created by users are
known as user-defined functions.
Advantages of user-defined function
The program will be easier to understand, maintain and debug.
Reusable codes that can be used in other programs.
A large program can be divided into smaller modules. Hence, a large project can
be divided among many programmers.
Three parts of a user defined functions are:
1) Function Declaration or Prototype
2) Function Definition
3) Function Call
2
Function Declaration
A function prototype is simply the declaration of a function that specifies function's
name, parameters and return type. It doesn't contain function body. A function prototype gives
information to the compiler that the function may later be used in the program.
Syntax
return_type function_name( parameter list );
Function Definition
A function definition in C programming consists of a function header and a function
body. Here are all the parts of a function:
Return Type: A function may return a value. The return_type is the data type of the
value the function returns. Some functions perform the desired operations without
returning a value. In this case, the return_type is the keyword void.
Function Name: The actual name of the function.
Arguments: When a function is invoked, you pass a value to the parameter. This value is
referred to as actual parameter or argument.
Function Body: The function body contains a collection of statements that define what
the function does.
Syntax:
return_type function_name( argument list )
{
body of the function
}
Function Call
Control of the program is transferred to the user-defined function by calling it. When a
program calls a function, the program control is transferred to the called function. A called
function performs a defined task and when its return statement is executed or when its function-
ending closing brace is reached, it returns the program control back to the main program.
Syntax:
functionName(parameter list);
Example:
int add(int,int,int); // function declaration
3
…..
……
int add(int a, int b, int c) // function definition
{
int sum = a+ b + c;
return sum;
}
void main()
{
int x=10,y=20,z=30;
int res = add(x,y,z); // function call
print(“Result=%d”,res);
}
Return Statement
The return statement terminates the execution of a function and returns a value to the
calling function. The program control is transferred to the calling function after the return
statement.
In the above example, the value of the sum variable is returned to the main function. The
res variable in the main() function is assigned this value.
Formal and Actual Parameters
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”. Also, the
arguments which A sends to B are called actual arguments and the parameters of B are
called formal arguments
o Formal Parameter: A variable and its type as they appear in the prototype of the
function or method.
o Actual Parameter: The variable or expression corresponding to a formal
parameter that appears in the function or method call in the calling environment.
In the above example, x,y and z in the main function are the actual parameter of add
function. Formal parameter of add function are a, b and c.
4
Pass by Value
In this parameter passing technique, a copy of actual parameter is passed to formal
parameter. As a result, any changes or modification happened to formal parameter
won’t reflect back to actual parameter. This can be explained with an example of
swapping program.
#include<stdio.h>
int swap(int a,int b)
{
int temp=a; a= b; b=temp;
}
void main()
{
int x,y;
printf("Enter the numbers:");
scanf("%d%d",&x,&y);
printf("Before swapping : x=%d\ty=%d\n",x,y);
swap(x,y);
printf("After swapping : x=%d\ty=%d",x,y);
}
Output:
Enter the numbers:10 20
Before swapping: x=10 y=20
After swapping : x=10 y=20
5
printf("Sum=%d",sum);
}
2) No arguments passed but return value
// function to read two number and return its sum
int add()
{
int a,b,sum;
printf("Enter the values of a & b");
scanf("%d%d",&a,&b);
sum = a+b;
return sum;
}
3) Arguments passed but no return value
// function that takes two arguments and print their sum.
void add(int a,int b)
{
int sum= a + b;
printf("Sum=%d",sum);
}
4) Arguments passed with return value
// function that takes two arguments and print their sum.
int add(int a,int b)
{
return a + b;
}
6
BUILT-IN FUNCTIONS (STRING FUNCTIONS, MATH FUNCTIONS)
7
RECURSION
A function that calls itself is known as a recursive function. And, this technique is known
as recursion. While using recursion, programmers need to be careful to define an exit condition
from the function, otherwise it will go into an infinite loop. Recursion makes program elegant.
However, if performance is vital, use loops instead as recursion is usually much slower. Write a
program to find factorial of number using recursive function
#include<stio.h>
int fact(int n)
{
if( n == 0)
{
return 1;
}
return n*fact(n-1);
}
void main()
{
int n;
printf("Enter the number:");
scanf("%d",&n);
printf("Factorial=%d",fact(n));
}
Output:
Enter the number:5
Factorial=120
Unlike linear search, there are a few conditions for applying binary search:
8
1. The list must be sorted.
2. Random access to the list member.
It means that we cannot apply the binary search in unsorted or liked data structures.
Algorithm for Binary Search in C
Let be the element we are searching for and the array is sorted in the ascending order.
1. Compare with the middle element of the array.
2. If matches with the middle element, we return the index of the middle element.
3. Else if is greater than the middle element, it means that can only lie in the right half
subarray after the middle element. So we repeat steps 1 and 2 for the right half subarray and
leave the left half subarray from the algorithm.
4. Else if is smaller than the middle element, it means that can only lie in the left
half subarray before the middle element. So, we repeat steps 1 and 2 for the left half
subarray.
5. We will keep doing that till we find or there is no element left in the subarray being
considered.
As we can see, the binary search ignores the half elements of the subarray after each pass. Due
to this, it is able to reduce the time required for searching the element in the array as compared
to linear search.
Example program:
#include <stdio.h>
// Recursive binary search function
int binarySearch(int arr[], int left, int right, int target) {
if (left <= right) {
int mid = left + (right - left) / 2;
// If the element is smaller than the middle element, then it can only be present in the left
subarray
9
if (arr[mid] > target)
return binarySearch(arr, left, mid - 1, target);
int main() {
int arr[] = {2, 3, 4, 10, 40, 50};
int target = 10;
int n = sizeof(arr) / sizeof(arr[0]);
int result = binarySearch(arr, 0, n - 1, target);
if (result != -1)
printf("Element is present at index %d\n", result);
else
printf("Element is not present in the array\n");
return 0;
}
Output:
Element is present at index 3
POINTERS
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.
10
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
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.
11
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.
12
}
// Driver program
int main()
{
sample();
return 0;
}
Output:
13
POINTER ARITHMETIC
Pointer Arithmetic is the set of valid arithmetic operations that can be performed on pointers.
The pointer variables store the memory address of another variable. It doesn’t store any
value. Hence, there are only a few operations that are allowed to perform on Pointers in C
language. The C pointer arithmetic operations are slightly different from the ones that we
generally use for mathematical calculations. These operations are:
1. Increment/Decrement of a Pointer
2. Addition of integer to a pointer
3. Subtraction of integer to a pointer
4. Subtracting two pointers of the same type
5. Comparison of pointers
1. Increment/Decrement of a Pointer
Increment: It is a condition that also comes under addition. 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.
Example:
If an integer pointer that stores address 1000 is incremented, then it will increment by 4(size
of an int), and the new address will point to 1004. While if a float type pointer is incremented
then it will increment by 4(size of a float) and the new address will be 1004.
14
Note: It is assumed here that the architecture is 64-bit and all the data types are sized
accordingly. For example, integer is of 4 bytes.
#include <stdio.h>
// pointer increment and decrement
//pointers are incremented and decremented by the size of the data type they point to
int main()
{
int a = 22;
int *p = &a;
printf("p = %u\n", p); // p = 6422288
p++;
printf("p++ = %u\n", p); //p++ = 6422292 +4 // 4 bytes
p--;
printf("p-- = %u\n", p); //p-- = 6422288 -4 // restored to original value
float b = 22.22;
float *q = &b;
printf("q = %u\n", q); //q = 6422284
q++;
printf("q++ = %u\n", q); //q++ = 6422288 +4 // 4 bytes
q--;
printf("q-- = %u\n", q); //q-- = 6422284 -4 // restored to original value
char c = 'a';
char *r = &c;
printf("r = %u\n", r); //r = 6422283
r++;
printf("r++ = %u\n", r); //r++ = 6422284 +1 // 1 byte
r--;
printf("r-- = %u\n", r); //r-- = 6422283 -1 // restored to original value
return 0;
}
15
Output:
p = 1441900792
p++ = 1441900796
p-- = 1441900792
q = 1441900796
q++ = 1441900800
q-- = 1441900796
r = 1441900791
r++ = 1441900792
r-- = 1441900791
2. Addition of Integer to Pointer
When a pointer is added with an integer value, the value is first multiplied by the size of the
data type and then added to the pointer.
Example:
Consider the same example as above where the ptr is an integer pointer that stores 1000 as an
address. If we add integer 5 to it using the expression, ptr = ptr + 5, then, the final address
stored in the ptr will be ptr = 1000 + sizeof(int) * 5 = 1020.
16
int *ptr1, *ptr2;
// Pointer stores the address of N
ptr1 = &N;
ptr2 = &N;
printf("Pointer ptr2 before Addition: ");
printf("%p \n", ptr2);
// Addition of 3 to ptr2
ptr2 = ptr2 + 3;
printf("Pointer ptr2 after Addition: ");
printf("%p \n", ptr2);
return 0;
}
Output:
Pointer ptr2 before Addition: 0x7ffca373da9c
Pointer ptr2 after Addition: 0x7ffca373daa8
Example:
Consider the same example as above where the ptr is an integer pointer that stores 1000 as an
address. If we subtract integer 5 from it using the expression, ptr = ptr – 5, then, the final
address stored in the ptr will be ptr = 1000 – sizeof(int) * 5 = 980.
Example:
Two integer pointers say ptr1(address:1000) and ptr2(address:1004) are subtracted. The
difference between addresses is 4 bytes. Since the size of int is 4 bytes, therefore
the increment between ptr1 and ptr2 is given by (4/4) = 1.
18
#include <stdio.h>
// Driver Code
int main()
{
int x = 6; // Integer variable declaration
int N = 4;
// Pointer declaration
int *ptr1, *ptr2;
ptr1 = &N; // stores address of N
ptr2 = &x; // stores address of x
printf(" ptr1 = %u, ptr2 = %u\n", ptr1, ptr2);
// %p gives an hexa-decimal value,
// We convert it into an unsigned int value by using %u
// Subtraction of ptr2 and ptr1
x = ptr1 - ptr2;
// Print x to get the Increment
// between ptr1 and ptr2
printf("Subtraction of ptr1 & ptr2 is %d\n",x);
return 0;
}
Output:
ptr1 = 2715594428, ptr2 = 2715594424
Subtraction of ptr1 & ptr2 is 1
5. Comparison of Pointers
We can compare the two pointers by using the comparison operators in C. We can implement
this by using all operators in C >, >=, <, <=, ==, !=. It returns true for the valid condition and
returns false for the unsatisfied condition.
1. Step 1: Initialize the integer values and point these integer values to the pointer.
2. Step 2: Now, check the condition by using comparison or relational operators on pointer
variables.
3. Step 3: Display the output.
19
// C Program to illustrare pointer comparision
#include <stdio.h>
int main()
{
// declaring array
int arr[5];
// declaring pointer to array name
int* ptr1 = &arr;
// declaring pointer to first element
int* ptr2 = &arr[0];
if (ptr1 == ptr2)
{
printf("Pointer to Array Name and First Element are Equal.");
}
else
{
printf("Pointer to Array Name and First Element are not Equal.");
}
return 0;
}
Output:
Pointer to Array Name and First Element are Equal.
20
Accessed using dereferencing
Accessed using square brackets [ ]
Accessing Elements operator * or pointer arithmetic.
notation. Example: int x = arr[2];
Example: int y = *ptr;
Pointers are variables that store
Not pointers themselves, but can
memory addresses. Array names
Relationship decay into pointers to their first
can decay into pointers to their first
elements in many contexts.
elements.
Can be incremented or
Increment and
Not applicable. decremented using ++ and --
Decrement
operators. Example: ptr++;
Can be used to navigate through
Pointer Arithmetic Not applicable. memory locations. Example: ptr =
ptr + 2;
Passing an array to a function
Pointers can be passed to functions
effectively passes a pointer to its
Passing to Functions directly. Example: void
first element. Example: void
printArray(int *ptr, int size);
printArray(int arr[], int size);
ARRAY OF POINTERS
Array and Pointers in C Language hold a very strong relationship. Generally, pointers are
the variables which contain the addresses of some other variables and with arrays a pointer stores
the starting address of the array. Array name itself acts as a pointer to the first element of the
array and also if a pointer variable stores the base address of an array then we can manipulate all
the array elements using the pointer variable only. Pointers can be associated with the
multidimensional arrays (2-D and 3-D arrays) as well. Also, We can create an array of pointers
to store multiple addresses of different variables.
What Is An Array?
An array in C is a collection of variables, all of the same type, accessed using a common
name. The individual elements in an array can be referenced by indexing them with a number,
starting from zero.
int numbers[5] = {1, 2, 3, 4, 5};
Here, numbers is an array of 5 integers.
21
What Is A Pointer?
A pointer in C is a variable that stores the address of another variable. Pointers are
powerful tools that allow direct memory access and manipulation.
int var = 10;
int *p;
p = &var;
Here, p is a pointer pointing to the memory location of var.
What Is An Array Of Pointers In C?
Pointers and Array representations are very much related to each other and can be
interchangeably used in the right context.
An array name is generally treated as a pointer to the first element of the array and if we
store the base address of the array in another pointer variable, then we can easily manipulate the
array using pointer arithmetic in a C Program.
Syntax
In a C Program, we denote array elements as arr[i], where i is the index value. Below is a
similar syntax in terms of pointers of how we can represent the array elements using the
dereferencing operator (*) on the array name i.e. using the pointers property of the array.
*(arr + i)
* is a dereferencing operator used to extract the value from the address (arr + i).
*(arr + i) is the same as arr[i] in a C Program.
arr represents the array name and i represents the index value.
#include <stdio.h>
int main()
{
// array declaration and initialization
int arr[5] = {2, 4, 6, 8, 10}, i;
for(i = 0; i < 5; i++)
{
// printing the elements address and value at
// arr[i] using *(arr + i) syntax
printf("[index %d] Address : %u, Value : %d\n", i, (arr + i), *(arr + i));
}
22
return 0;
}
Output:
[Success] Your code was executed successfully
[index 0] Address : 2364420656, Value : 2
[index 1] Address : 2364420660, Value : 4
[index 2] Address : 2364420664, Value : 6
[index 3] Address : 2364420668, Value : 8
[index 4] Address : 2364420672, Value : 10
23
return 0;
}
Output:
Before swap: a = 10, b = 20
After swap: a = 10, b = 20
24