UNIT III
UNIT III
UNIT – III
FUNCTIONS AND POINTERS Introduction to functions: Function prototype,
function definition, function call, Built-in functions (string functions, math functions) –
Recursion – Example Program: Computation of Sine series, Scientific calculator using built-
in functions, Binary Search using recursive functions – Pointers – Pointer operators –
Pointer arithmetic – Arrays and pointers – Array of pointers – Example Program: Sorting of
names – Parameter passing: Pass by value, Pass by reference – Example Program:
Swapping of two numbers and changing the value of a variable using pass by reference
#include <stdio.h>
void functionName()
{
... .. ...
TPGIT/CSE 1
CS8251 Dept of CSE Programming in C
... .. ...
}
int main()
{
... .. ...
... .. ...
functionName();
... .. ...
... .. ...
}
void functionName()
And, the compiler starts executing the codes inside the user-defined function.
The control of the program jumps to statement next to functionName(); once all the
codes inside the function definition are executed.
A function is a block of code that performs a specific task.
C allows you to define functions according to your need. These functions are known as
user-defined functions. For example:
Suppose, you need to create a circle and color it depending upon the radius and color.
You can create two functions to solve this problem:
createCircle() function
color() function
Example: User-defined function
Here is a example to add two integers. To perform this task, a user-defined
function addNumbers() is defined.
#include <stdio.h>
int main()
{
int n1,n2,sum;
printf("sum = %d",sum);
TPGIT/CSE 2
CS8251 Dept of CSE Programming in C
return 0;
}
In the above example, int addNumbers(int a, int b); is the function prototype which
provides following information to the compiler:
1. name of the function is addNumbers()
2. return type of the function is int
3. two arguments of type int are passed to the function
The function prototype is not needed if the user-defined function is defined before
the main() function.
3.1.2 Function definition
Function definition contains the block of code to perform a specific task i.e. in this case,
adding two numbers and returning it.
When a function is called, the control of the program is transferred to the function
definition. And, the compiler starts executing the codes inside the body of a function.
3.1.3 Function Call
Control of the program is transferred to the user-defined function by calling it.
TPGIT/CSE 3
CS8251 Dept of CSE Programming in C
In the above example, function call is made using addNumbers(n1,n2); statement inside
the main().
The type of arguments passed to a function and the formal parameters must match,
otherwise the compiler throws error.
If n1 is of char type, a also should be of char type. If n2 is of float type, variable b also
should be of float type.
A function can also be called without passing an argument.
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 return
statement.
In the above example, the value of variable result is returned to the variable sum in
the main() function.
return (expression);
TPGIT/CSE 4
CS8251 Dept of CSE Programming in C
For example,
return a;
return (a+b);
The type of value returned from the function and the return type specified in function
prototype and function definition must match.
void checkPrimeNumber();
int main()
{
checkPrimeNumber(); // no argument is passed to prime()
return 0;
}
TPGIT/CSE 5
CS8251 Dept of CSE Programming in C
// return type of the function is void becuase no value is returned from the function
void checkPrimeNumber()
{
int n, i, flag=0;
int main()
{
int n, i, flag = 0;
if (flag == 1)
TPGIT/CSE 6
CS8251 Dept of CSE Programming in C
return 0;
}
return n;
}
The empty parentheses in n = getInteger(); statement indicates that no argument is
passed to the function. And, the value returned from the function is assigned to n.
Here, the getInteger() function takes input from the user and returns it. The code to
check whether a number is prime or not is inside the main() function.
Example #3: Argument passed but no return value
#include <stdio.h>
void checkPrimeAndDisplay(int n);
int main()
{
int n;
return 0;
}
TPGIT/CSE 7
CS8251 Dept of CSE Programming in C
break;
}
}
if(flag == 1)
printf("%d is not a prime number.",n);
else
printf("%d is a prime number.", n);
}
The integer value entered by the user is passed to checkPrimeAndDisplay()function.
Here, the checkPrimeAndDisplay() function checks whether the argument passed is a
prime number or not and displays the appropriate message.
Example #4: Argument passed and a return value
#include <stdio.h>
int checkPrimeNumber(int n);
int main()
{
int n, flag;
if(flag==1)
printf("%d is not a prime number",n);
else
printf("%d is a prime number",n);
return 0;
}
return 0;
TPGIT/CSE 8
CS8251 Dept of CSE Programming in C
}
The input from the user is passed to checkPrimeNumber() function.
The checkPrimeNumber() function checks whether the passed argument is prime or
not. If the passed argument is a prime number, the function returns 0. If the passed
argument is a non-prime number, the function returns 1. The return value is assigned
to flag variable.
Then, the appropriate message is displayed from the main() function.
Which approach is better?
Well, it depends on the problem you are trying to solve. In case of this problem, the last
approach is better.
A function should perform a specific task. The checkPrimeNumber() function doesn't
take input from the user nor it displays the appropriate message. It only checks whether
a number is prime or not, which makes code modular, easy to understand and debug.
3.1.4 Built-in functions
Some of the "commands" in C are not really "commands" at all but are functions. For
example, we have been using printf and scanf to do input and output, and we have
used rand to generate random numbers - all three are functions.
There are a great many standard functions that are included with C compilers and
while these are not really part of the language, in the sense that you can re-write them if
you really want to, most C programmers think of them as fixtures and fittings. Later in
the course we will look into the mysteries of how C gains access to these standard
functions and how we can extend the range of the standard library. But for now a list of
the most common libraries and a brief description of the most useful functions they
contain follows:
1. stdio.h: I/O functions:
a. getchar() returns the next character typed on the keyboard.
b. putchar() outputs a single character to the screen.
c. printf() as previously described
d. scanf() as previously described
2. string.h: String functions
a. strcat() concatenates a copy of str2 to str1
b. strcmp() compares two strings
c. strcpy() copys contents of str2 to str1
3. ctype.h: Character functions
a. isdigit() returns non-0 if arg is digit 0 to 9
b. isalpha() returns non-0 if arg is a letter of the alphabet
c. isalnum() returns non-0 if arg is a letter or digit
d. islower() returns non-0 if arg is lowercase letter
e. isupper() returns non-0 if arg is uppercase letter
4. math.h: Mathematics functions
a. acos() returns arc cosine of arg
b. asin() returns arc sine of arg
c. atan() returns arc tangent of arg
d. cos() returns cosine of arg
e. exp() returns natural logarithim e
f. fabs() returns absolute value of num
g. sqrt() returns square root of num
TPGIT/CSE 9
CS8251 Dept of CSE Programming in C
TPGIT/CSE 10
CS8251 Dept of CSE Programming in C
hyperbolic sine.
String
functions Description
TPGIT/CSE 11
CS8251 Dept of CSE Programming in C
TPGIT/CSE 12
CS8251 Dept of CSE Programming in C
specified string
3.2 Recursion
Recursion is the process of repeating items in a self-similar way. In programming
languages, if a program allows you to call a function inside the same function, then it is
called a recursive call of the function.
void recursion() {
recursion(); /* function calls itself */
}
int main()
{ recursion()
;
}The C programming language supports recursion, i.e., a function to call itself. But
while using recursion, programmers need to be careful to define an exit condition from
the function, otherwise it will go into an infinite loop.
Recursive functions are very useful to solve many mathematical problems, such as
calculating the factorial of a number, generating Fibonacci series, etc.
NumberFactorial
The following example calculates the factorial of a given number using a recursive
function −
#include <stdio.h>
{if(i <= 1) {
return 1;
}
return i * factorial(i - 1);
}
int main()
{ int i = 12;
printf("Factorial of %d is %d\n", i, factorial(i));
return 0;
}
When the above code is compiled and executed, it produces the following result −
Factorial of 12 is 479001600
FibonacciSeries
The following example generates the Fibonacci series for a given number using a
recursive function −
#include <stdio.h>
int fibonacci(int i) {
TPGIT/CSE 13
CS8251 Dept of CSE Programming in C
if(i == 0)
{return 0;
}
if(i == 1)
{return 1;
}
return fibonacci(i-1) + fibonacci(i-2);
}
int main()
{ int i;
return 0;
}
When the above code is compiled and executed, it produces the following result −
0
1
1
2
3
5
8
13
21
34
3.3 Example Program:
3.3.1 Computation of Sine series Sine Series:
Sine Series is a series which is used to find the value of Sin(x).where,
x is the angle in degree which is converted to Radian.
The formula used to express the Sin(x) as Sine Series is
For example,
Let the value of x be 30.
TPGIT/CSE 14
CS8251 Dept of CSE Programming in C
void main()
{
int i, n;
float x, sum, t;
clrscr();
x=x*3.14159/180;
t=x;
sum=x;
TPGIT/CSE 15
CS8251 Dept of CSE Programming in C
TPGIT/CSE 16
CS8251 Dept of CSE Programming in C
4. #include <stdio.h>5.
6. void binary_search(int [], int, int, int);
7. void bubble_sort(int [], int);
8.
9. int main()
10. {
11. int key, size, i;
12. int list[25];
13.
14. printf("Enter size of a list: ");
15. scanf("%d", &size);
16. printf("Generating random numbers\n");
17. for(i = 0; i < size; i++)
18. {
19. list[i] = rand() % 100;
20. printf("%d ", list[i]);
21. }
22. bubble_sort(list, size);
23. printf("\n\n");
24. printf("Enter key to search\n");
25. scanf("%d", &key);
26. binary_search(list, 0, size, key);
27.
28. }
29.
30. void bubble_sort(int list[], int size)
31. {
32. int temp, i, j;
33. for (i = 0; i < size; i++)
34. {
35. for (j = i; j < size; j++)
36. {
37. if (list[i] > list[j])
38. {
39. temp = list[i];
40. list[i] = list[j];
41. list[j] = temp;
42. }
43. }
44. }
45. }
46.
47. void binary_search(int list[], int lo, int hi, int key)
48. {
49. int mid;
50.
TPGIT/CSE 17
CS8251 Dept of CSE Programming in C
Output:
Enter size of a list: 10
Generating random numbers
83 86 77 15 93 35 86 92 49 21
3.4 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];
TPGIT/CSE 18
CS8251 Dept of CSE Programming in C
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
WhatarePointers?
A pointer is a variable whose value is the address of another variable, i.e., direct
address of the memory location. Like any variable or constant, you must declare a
pointer before using it to store any variable address. The general form of a pointer
variable declaration is −
type *var-name;
Here, type is the pointer's base type; it must be a valid C data type and var-name is the
name of the pointer variable. The asterisk * used to declare a pointer is the same
asterisk used for multiplication. However, in this statement the asterisk is being used
to designate a variable as 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.
HowtoUsePointers?
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.
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 () {
TPGIT/CSE 19
CS8251 Dept of CSE Programming in C
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
NULLPointers
It is always a good practice to assign a NULL value to a pointer variable in case you do
not have an exact address to be assigned. This is done at the time of variable
declaration. A pointer that is assigned NULL is called a null pointer.
The NULL pointer is a constant with a value of zero defined in several standard
libraries. Consider the following program −
#include <stdio.h>
int main () {
return 0;
}
When the above code is compiled and executed, it produces the following result −
The value of ptr is 0
In most of the operating systems, programs are not permitted to access memory at
address 0 because that memory is reserved by the operating system. However, the
memory address 0 has special significance; it signals that the pointer is not intended to
point to an accessible memory location. But by convention, if a pointer contains the
null (zero) value, it is assumed to point to nothing.
To check for a null pointer, you can use an 'if' statement as follows −
if(ptr) /* succeeds if p is not null */
if(!ptr) /* succeeds if p is null */
3.5 Pointer Operator
Operator Operator Name Purpose
TPGIT/CSE 20
CS8251 Dept of CSE Programming in C
In order to create pointer to a variable we use “*” operator and to find the address of
variable we use “&” operator.
Don’t Consider “&” and “*” operator as Logical AND and Multiplication Operator in
Case of Pointer.
ImportantNotes:
1. ‘&’ operator is called as address Operator
2. ‘*’ is called as ‘Value at address’ Operator
3. ‘Value at address’ Operator gives ‘Value stored at Particular address.
4. ‘Value at address’ is also called as ‘Indirection Operator’
PointerOperators:
#include<stdio.h>
int main()
{
int n = 20;
printf("\nThe address of n is %u",&n);
printf("\nThe Value of n is %d",n);
printf("\nThe Value of n is %d",*(&n));
}
Output:
The address of n is 1002
The Value of n is 20
The Value of n is 20
How *(&n) is same as printing the value of n ?
&n Gives address of the memory location whose name is ‘n’
TPGIT/CSE 21
CS8251 Dept of CSE Programming in C
int main () {
TPGIT/CSE 22
CS8251 Dept of CSE Programming in C
return 0;
}
When the above code is compiled and executed, it produces the following result −
Address of var[0] = bf882b30
Value of var[0] = 10
Address of var[1] = bf882b34
Value of var[1] = 100
Address of var[2] = bf882b38
Value of var[2] = 200
Decrementinga Pointer
The same considerations apply to decrementing a pointer, which decreases its value by
the number of bytes of its data type as shown below −
#include <stdio.h>
int main () {
return 0;
}
When the above code is compiled and executed, it produces the following result −
Address of var[2] = bfedbcd8
Value of var[2] = 200
TPGIT/CSE 23
CS8251 Dept of CSE Programming in C
int main () {
return 0;
}
When the above code is compiled and executed, it produces the following result −
Address of var[0] = bfdbcb20
Value of var[0] = 10
Address of var[1] = bfdbcb24
Value of var[1] = 100
Address of var[2] = bfdbcb28
Value of var[2] = 200
3.7 Arrays and Pointers
TPGIT/CSE 24
CS8251 Dept of CSE Programming in C
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.
This can be demonstrated by an example:
#include <stdio.h>
int main()
{
char charArr[4];
int i;
return 0;
}
When you run the program, the output will be:
int arr[4];
TPGIT/CSE 25
CS8251 Dept of CSE Programming in C
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.
Since, the addresses of both are the same, the values of arr and &arr[0] are also the
same.
Similarly,
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));
Enter 6 numbers:
2
3
4
5
TPGIT/CSE 26
CS8251 Dept of CSE Programming in C
3
4
Sum = 21
int main () {
return 0;
}
When the above code is compiled and executed, it produces the following result −
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200
There may be a situation when we want to maintain an array, which can store pointers
to an int or char or any other data type available. Following is the declaration of an
array of pointers to an integer −
int *ptr[MAX];
It declares ptr as an array of MAX integer pointers. Thus, each element in ptr, holds a
pointer to an int value. The following example uses three integers, which are stored in
an array of pointers, as follows −
#include <stdio.h>
int main () {
TPGIT/CSE 27
CS8251 Dept of CSE Programming in C
return 0;
}
When the above code is compiled and executed, it produces the following result −
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200
You can also use an array of pointers to character to store a list of strings as follows −
#include <stdio.h>
int main () {
char *names[] =
{"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali"
};
int i = 0;
return 0;
}
When the above code is compiled and executed, it produces the following result −
Value of names[0] = Zara Ali
Value of names[1] = Hina Ali
Value of names[2] = Nuha Ali
Value of names[3] = Sara Ali
3.9 Example Program
Sorting of names
/* This program would sort the input strings in
* an ascending order and would display the same
*/
#include<stdio.h>
TPGIT/CSE 28
CS8251 Dept of CSE Programming in C
#include<string.h>
int main(){
int i,j,count;
char str[25][25],temp[25];
puts("How many strings u are going to enter?: ");
scanf("%d",&count);
return 0;
}
Output:
TPGIT/CSE 29
CS8251 Dept of CSE Programming in C
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
3.10.1 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>
// Passing parameters
func(x, y);
printf("In main, x = %d y = %d\n", x, y);
return 0;
}
Output:
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
3.10.2 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
TPGIT/CSE 30
CS8251 Dept of CSE Programming in C
int main(void)
{
int a = 10, b = 20;
// passing parameters
swapnum(&a, &b);
Output:
a is 20 and b is 10
int main()
{
int x, y, temp;
temp = x;
x = y;
y = temp;
TPGIT/CSE 31
CS8251 Dept of CSE Programming in C
return 0;
}
Output of program:
int main()
{
int x, y;
swap(&x, &y);
return 0;
}
//Swap function definition
void swap(int *a, int *b)
{
int t;
t = *b;
*b = *a;
*a = t;
}
TPGIT/CSE 32
CS8251 Dept of CSE Programming in C
Output of program:
TPGIT/CSE 33