Professional Documents
Culture Documents
Unit Iv Functions and Pointers
Unit Iv Functions and Pointers
Programmer working on large project can divide the workload by making different
functions.
Function definition:
Syntax:
return-type function-name (parameter-list)
{
function-body ;
}
The first line return-type function-name(parameter) is known as function header and the
statement within curly braces is called function body.
return-type:return type specifies the type of value(int,float,char,double) that function is
expected to return to the program calling the function.
function-name:function name specifies the name of the function. The function name is any valid
C identifier
parameter-list:The parameter list declares the variables that will receive the data sent by calling
program. They often referred to as formal parameters. These parameters are also used to send
values to calling program.
function-body: The function body contains the declarations and the statement necessary for
performing the required task. The body is enclosed within curly braces { } and consists of three
parts.
local variable declaration
function statement that performs the tasks of the function
a return statement that return the value evaluated by the function.
Function call:
A function call is an expression that passes control and arguments to a function
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.
To call a function, you simply need to pass the required parameters along with the
function name, and if the function returns a value, then you can store the returned value.
Example:
/*Program to demonstrate the working of user defined function*/
#include <stdio.h>
int add(int a, int b); //function prototype(declaration)
int main(){
int num1,num2,sum;
Return Statement
Return statement is used for returning a value from function definition to calling function.
Syntax:
return (expression);
For example:
return a;
return (a+b);
In above example, value of variable add in add() function is returned and that value is
stored in variable sum in main() function.
The data type of expression in return statement should also match the return type of
function.
Suppose that the three functions are stored in three files called main.c, qetline. c, and
strindex. c. Then the command
cc main.cgetline.cstrindex.c
compiles the three files, placing the resulting object code in files main.0, qetline.o, and
strindex. 0, then loads them all into an executable file called a. out
Arguments that are passed in function call and arguments that are accepted in function
definition should have same data type.
For example: If argument num1 was of int type and num2 was of float type then, argument
variable a should be of type int and b should be of type float,i.e., type of argument during
function call and function definition should be same.
A function can be called with or without an argument.
If a function is to use arguments, it must declare variables that accept the values of the
arguments. These variables are called the formal parameters of the function.
Formal parameters behave like other local variables inside the function and are created upon
entry into the function and destroyed upon exit.
While calling a function, there are two ways in which arguments can be passed to a function
2 Changes made inside the function is not Changes made inside the function is
reflected on other functions reflected outside the function also
3 Actual and formal arguments will be created Actual and formal arguments will be
in different memory location created in same memory location
Formal Parameters
Formal parameters, are treated as local variables with-in a function and they take precedence
over global variables.
If the return data type of a function is “void”, then, it can‟t return any values to the calling
function.
If the return data type of the function is other than void such as “int, float, double etc”, then,
it can return values to the calling function.
1) Functions with no arguments and no return value in C :
Functions where no arguments will be passed in the function call in the main() and no return
values from the function definition as shown below:
/*Program to demonstrate the working of user defined function*/
#include <stdio.h>
void add(); //function prototype(declaration)
void main(){
add(); //function call
}
void add() //function definition
{
int num1,num2,sum;
Output:
Enters two number to add
56
sum=11
}
Output:
Enters two number to add
56
sum=11
Recursive functions can be controlled by making sure that there is a safe way to exit them at
some point in the chain of function calls.
A standard example of controlled recursion is the factorial function. The factorial function is
defined to be the product (multiplication) of all integers from 1 to the parameter of the
function. (The factorial of 0 is 1.)
Here are some examples of the factorial function. (pseudocode )
factorial(3) == 1 * 2 * 3 == 6
factorial(4) == 1 * 2 * 3 * 4 == 24
factorial(3) == 1 * 2 * 3 * 4 * 5 == 120
the factorial function is defined by two equations.
factorial(n) = n * factorial(n-1)
factorial(0) = 1
Code example:
#include <stdio.h>
int factorial (int n)
{
if (n == 0)
return 1;
else
return (n * factorial (n-1));
}
Output:
Enter the element:
3
factotial of 3 is 6
The main function prints the value of factorial(3). First, the factorial function is called with
the parameter 3. The function tests whether its parameter n is zero.
It is not, so it takes the else branch if the if statement, which instructs it to return the value
of factorial(3-1). It therefore calls itself recursively with a parameter of 2.
The new call checks whether its parameter is zero. It isn't (it's 2), so it takes the else branch
again, and tries to calculate 2 * factorial (1).
In order to do so, it calls itself recursively with a value of 2-1, or 1. The new call checks
whether its parameter is zero.
It is actually 1, so it takes the else branch again and attempts to calculate 1 * factorial (0). In
order to do so, it calls itself again with the parameter 0.
Again, the function checks whether its parameter is zero. This time it is, so the function
bottoms out. It takes the first branch of the if statement and returns a value of 1.
Now the previous function call can also return a value, and so on, until the very first call
to factorial terminates, and the function returns a value of 6.
To sum up, the expression factorial(3) goes through the following steps before finally being
evaluated:
factorial (3) == 3 * factorial(2)
== 3 * (2 * factorial(1))
== 3 * (2 * (1 * factorial(0)))
== 3 * (2 * (1 * 1)))
== 6
Warning of using recursive function:
Recursive function must have at least one terminating condition that can be satisfied.
Otherwise, the recursive function will call itself repeatably until the run time stack overflows.
I 5 65524
J 65524 65522
Example :
#include <stdio.h>
void main()
{
int *ptr, i;
i = 11;
/* address of i is assigned to ptr */
ptr = &i;
/* show i's value using ptr variable */
printf("Value of i : %d", *ptr);
}
OUTPUT: Value of i : 11
after Assigning the address of variable to pointer , i.e after the execution of this statement
ptr = &i;
(a+b) will evaluate addition of values present in variables and output of (a+b)is nothing but
Literal, so we cannot use Address operator
&(a+b)
Variable may be integer,character,float but the address of the variable is always integer so
Pointer requires 2 bytes of memory in Turbo C Compiler. This requirement is different for
different Compilers
Dereferencing Pointer:
Asterisk(*) indirection operator is used along with pointer variable while Dereferencing the
pointer variable.
Asterisk Operator is also called as value at operator
Dereferencing Operation is performed to access or manipulate data contained in memory
location pointed to by a pointer
ptr = &arr;
ptr++;
5. Integer value can be added or Subtracted from Pointer variable
intarr[20];
int *ptr;
ptr = &arr;
ptr = ptr + 2; //arr[2] will be accessed
6. When two Pointer points to same array then one Pointer variable can be Subtracted from
another
7. Two Pointers pointing to objects of same data type then they can be compared using the
Relational Operator
8. Value cannot be assigned to arbitrary address
int *ptr;
ptr = 100; //Illegal
9. Pointer Variable cannot be multiplied by Constant
int *ptr;
ptr = ptr * 6; //Illegal
Advantages of pointer
1) Pointer reduces the code and improves the performance, it is used to retrieving strings, trees
etc. and used with arrays, structures and functions.
2) We can return multiple values from function using pointer.
3) It makes you able to access any memory location in the computer's memory.
Pointer Applications:
1. Passing Parameter by Reference
Pointer is used to pass parameter to function. In this scheme we are able to modify value
at direct memory location.
2. Accessing Array element
We can access array using pointer. We can store base address of array in pointer. we can
access each and individual location using pointer.
3. Dynamic Memory Allocation :
We can use pointer to allocate memory dynamically. Malloc and calloc function is used
to allocate memory dynamically.
4. Reducing size of parameter
Suppose we want to pass the structure to the function then we can pass structure to the
function using pointer in order to save memory.
5. Passing Strings to function
6. Provides effective way of implementing the different data structures such as tree,graph,linked
list
VOID POINTER:
Instead of declaring different types of pointer variable it is feasible to declare single pointer
variable which can act as integer pointer, character pointer.
General Purpose Pointer is called as void Pointer.
It does not have any data type associated with it
It can store address of any type of variable
charcnum;
intinum;
floatfnum;
ptr = &cnum; // ptr has address of character data
ptr = &inum; // ptr has address of integer data
ptr = &fnum; // ptr has address of float data
When we assign address of integer to the void pointer, pointer will become Integer Pointer.
When we assign address of Character Data type to void pointer it will become Character
Pointer.
Similarly we can assign address of any data type to the void pointer.
It is capable of storing address of any data type
Pointer arithmetic can not be performed in a void pointer.
Example:-
void *ptr;
int a;
ptr=&a;
ptr++; // This statement is invalid and will result in an error because 'ptr' is a void pointer
variable.
take the data pointed to by a void pointer we typecast it with the correct type of the data holded
inside the void pointers location.
#include<stdio.h>
void main()
{
void *ptr; // ptr is declared as Void pointer
charcnum='A';
intinum=10;
floatfnum=2.3;
ptr = &cnum; // ptr has address of character data
printf("char pointer=%c\n",*(char*)ptr);
ptr = &inum; // ptr has address of integer data
printf("Int pointer=%d\n",*(int*)ptr);
ptr = &fnum;
printf("float pointer=%f\n",*(float*)ptr);
}
Output:
char pointer=A
Int pointer=10
float pointer=2.300000
Incrementing a Pointer
We prefer using a pointer in our program instead of an array because the variable pointer can
be incremented, unlike the array name which cannot be incremented because it is a constant
pointer.
The following program increments the variable pointer to access each succeeding element of
the array –
#include <stdio.h>
const int MAX = 3;
void main () {
int var[] = {10, 100, 200};
int i, *ptr;
/* let us have array address in pointer */
ptr = var;
for ( i = 0; i < MAX; i++) {
printf("Address of var[%d] = %x\n", i, ptr );
printf("Value of var[%d] = %d\n", i, *ptr );
/* move to the next location */
ptr++;
}
}
OUTPUT:
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
Decrementing a 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>
const int MAX = 3;
void main () {
int var[] = {10, 100, 200};
int i, *ptr;
/* let us have array address in pointer */
ptr = &var[MAX-1];
for ( i = MAX; i > 0; i--) {
printf("Address of var[%d] = %x\n", i, ptr );
printf("Value of var[%d] = %d\n", i, *ptr );
/* move to the previous location */
ptr--;
}
}
OUTPUT:
Address of var[3] = bfedbcd8
Value of var[3] = 200
Address of var[2] = bfedbcd4
Value of var[2] = 100
Address of var[1] = bfedbcd0
Value of var[1] = 10
Expression Result
int main()
{
inta,b;
int *ptr1,*ptr2;
ptr1 = &a; //assume address of a as 1000
ptr2 = &b; // assume address of b as 2000
if(ptr2 > ptr1)
printf("Ptr2 is far from ptr1");
return(0);
}
Output:
Ptr2 is far from ptr1
MEANING OF (*++ptr) :
Consider the Following Example :
#include<stdio.h>
int main()
{
int n = 20 , *ptr ;
ptr = &n;
printf("%d",*++ptr);
return(0);
}
Output :
Garbage Value gets printed
‘++’ and ‘*’ both have Equal Precedence
Associativity is from Right to Left ( Expression evaluated from R->L)
Both are Unary (Operates on single operand )
So „ ++ „ is Performed First then „ * „
Calculation of Answer :
* ++ptr= *(++ptr )
= *( 3060 )
= Value Stored at Location 3060
This operation should not be used in normal operation.
Perform this operation if we have consecutive memory i.e Array.
If we perform this operation in above example then we will get garbage value as we dont know
the value stored at 3060.
*++ptr in Array:
#include<stdio.h>
int main()
{
intarr[5] = {10,20,30,40,50};
int *ptr ;
ptr = &arr;
printf("%d",*++ptr);
return(0);
}
Output :
20
ptr = #
printf("Value of ++*ptr : %d",++*ptr);
return(0);
}
Output :
11
Example 2 : Consider *ptr++
#include<stdio.h>
int main()
{
intnum = 10;
int *ptr;
ptr = #
printf("Value of *ptr++ : %d", *ptr++);
return(0);
}
Output :
10
Hence, ++*ptr and *ptr++ are not same
*ptr 45
**ptr2ptr 45
Ptr &n
ptr2ptr &ptr
Example :
#include<stdio.h>
int main()
{
intnum = 45 , *ptr , **ptr2ptr ;
ptr = #
ptr2ptr = &ptr;
printf("%d",**ptr2ptr);
return(0);
}
Output :
45
Program :
#include<stdio.h>
#include<conio.h>
void main()
{
int i =50;
int **ptr1;
int *ptr2;
clrscr();
ptr2 = &i;
ptr1 = &ptr2;
printf("\nThe value of **ptr1 : %d",**ptr1);
NULL POINTERS
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.
#include <stdio.h>
int main () {
int *ptr = NULL;
printf("The value of ptr is : %x\n", ptr );
return 0;
}
OUTPUT:
The value of ptr is 0
Here variable arr will give the base address, which is a constant pointer pointing to the
element, arr[0]. Therefore arr is containing the address of arr[0] i.e 1000.
arr is equal to &arr[0] // by default
We can declare a pointer of type int to point to the array arr.
int *p;
p = arr;
or p = &arr[0]; //both the statements are equivalent.
Now we can access every element of array arr using p++ to move from one element to another.
NOTE : You cannot decrement a pointer once incremented. p-- won't work.
we can use that pointer to access the array. Lets have an example,
int i;
int a[5] = {1, 2, 3, 4, 5};
int *p = a; // same as int*p = &a[0]
#include <stdio.h>
int main( )
{
/*Pointer variable*/
int *p;
/*Array declaration*/
intval[7] = { 11, 22, 33, 44, 55, 66, 77 } ;
/* Assigning the address of val[0] to pointer: 88820*/
p = &val[0];
for ( int i = 0 ; i <= 6 ; i++ )
{
printf("val[%d]: value is %d and address is %u", i, *p, p);
p++;
}
return 0;
}
OUTPUT:
val[0]: value is 11 and address is 3218280764
val[1]: value is 22 and address is 3218280768
val[2]: value is 33 and address is 3218280772
val[3]: value is 44 and address is 3218280776
val[4]: value is 55 and address is 3218280780
val[5]: value is 66 and address is 3218280784
val[6]: value is 77 and address is 3218280788
Points to Note:
1) Pointer variable data type is same as the type of array – Integer in above example.
2) Pointer has been initialized by array 1st element address(subscript 0 for e.g. &val[0]).
3) In the loop the increment operation(p++) is performed on the pointer variable to get the next
location, this arithmetic is same for all types of arrays (for all data types double, char, int etc..)
even though the bytes consumed by each data type is different.
4) In the above program, the statement p=&val[0], instead we can also use p=val.
POINTER LOGIC
You must have understood the logic in above code so now its time to play with few pointer
arithmetic and expressions.
if p = &val[0] which means
*p ==val[0]
(p+1) == &val[2] & *(p+1) == val[2]
(p+2) == &val[3] & *(p+2) == val[3]
(p+n) == &val[n+1) & *(p+n) == val[n+1]
Now its time to rewrite our old example program in a better way –
#include <stdio.h>
int main( )
{
int *p;
intval[7] = { 11, 22, 33, 44, 55, 66, 77 } ;
p = &val[0];
for ( int i = 0 ; i <= 6 ; i++ )
{
printf("val[%d]: value is %d and address is %u", i, *(p+i), (p+i));
}
return 0;
}
ARRAY OF POINTERS
We can also have array of pointers. Pointers are very helpful in handling character array with
rows of varying length.
char *name[3]={
"Adam",
"chris",
"Deniel"
};
//Now see same array without using pointer
char name[3][20]= {
"Adam",
"chris",
"Deniel"
};
if(flag == 1)
printf("%d ",i);
}
return 0;
}
break;
}
}
return flag;
}
OUTPUT:
Enter two positive integers: 12
30
Prime numbers between 12 and 30 are: 13 17 19 23 29
void main () {
/* local variable definition */
int a = 100;
int b = 200;
int ret;
/* calling a function to get max value */
ret = max(a, b);
printf( "Max value is : %d\n", ret );
}
else
result = num2;
return result;
}
OUTPUT:
Max value is : 200
length = string_ln(str);
printf("The length of the given string %s is : %d", str, length);
}
OUTPUT:
Enter the String: pritesh
Length of the given string priteshis : 7
5. Write a ‘C’ Program to compute the sum of all elements stored in an array using
pointers
#include<stdio.h>
#include<conio.h>
void main() {
int numArray[10];
int i, sum = 0;
int *ptr;
printf("\nEnter 10 elements : ");
for (i = 0; i < 10; i++)
scanf("%d", &numArray[i]);
ptr = numArray; /* a=&a[0] */
for (i = 0; i < 10; i++) {