0% found this document useful (0 votes)
25 views39 pages

CP Unit-IV - RIT CSE (1)

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)
25 views39 pages

CP Unit-IV - RIT CSE (1)

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/ 39

I B.

TECH I SEM CSE

Programming For Problem Solving Using C

UNIT-IV
FUNCTIONS & POINTERS

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.
You can divide up your code into separate functions. How you divide up your code among different
functions is up to you, but logically the division is such that each function performs a specific task.
A function declaration tells the compiler about a function's name, return type, and parameters. A
function definition provides the actual body of the function.

C function can be classified into two categories


1) Library functions.
2) User defined functions.
main( ) is an example of user defined function. printf(), scanf(), sqrt(), cos(), strcat() belong to the
category of library functions.

 Every program must have a main() function to indicate where the program has to begin its
execution. If a program was coded as a single function, the program may become too large and
complex and as a result, the task of debugging, testing and maintaining becomes difficult.

 If a program is divided into functional parts then each part may be independently coded and
later combined into a single unit. These sub programs called functions are must easier to
understand, debug and test. A function is a self-contained block of code that performs a
particular task.

Function Declarations
A function declaration tells the compiler about a function name and how to call the function. The
actual body of the function can be defined separately.
SYNTAX OF function declaration:
return_type function_name( parameter list );

SYNTAX OF function definition:

type function_name (argument list)


{
local variable declarations;
stmt1;
stmt2;
-
-
return (expression);
}

A function definition in C programming consists of a function header and a function body. Here are
all the parts of a function −

CSE, RIT Page 1


I B.TECH I SEM CSE

 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 − This is the actual name of the function. The function name and the
parameter list together constitute the function signature.
 Parameters − A parameter is like a placeholder. When a function is invoked, you pass a value
to the parameter. This value is referred to as actual parameter or argument. The parameter list
refers to the type, order, and number of the parameters of a function. Parameters are optional;
that is, a function may contain no parameters.
 Function Body − The function body contains a collection of statements that define what the
function does.

Calling a Function
While creating a C function, you give a definition of what the function has to do. To use a function,
you will have to call that function to perform the defined task.
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.

TYPES OF FUNCTION DECLARATIONS:

A function can be declared with

1. Return value and arguments


2. Only arguments without return value
3. With return value and without arguments
4. Without return value and without arguments:

Example for Defining function with return value and arguments:

Example
#include <stdio.h>

int mul(a,b)
int a,b;
{
int m;
m=a*b;
return(m);
}
void main( )
{
int m,n,p; clrscr();
printf(“enter two numbers “);
scanf(“%d%d”,&m,&n);
p=mul(m,n); /*------- function call */
printf(“%d\n”,p);
}

CSE, RIT Page 2


I B.TECH I SEM CSE

When the compiler encounters a function call, the control is transferred to the function mul(x,y). This
function is then executed line by line and a value is returned when a return statement is encountered.
This value is assigned to p.

Points to remember:
1. A function may or may not return a value if it does, it can return only one value.
2. Functions return integer value by default.
3. When a function is supposed to return a non-integer value, its type must be explicitly specified in
the function header. Such a function should be declared at the start of the calling function.

Example: Function with arguments and without return value

/*program to add two numbers using a function*/


#include<stdio.h>
Void sum(x,y)
{
int res;
res = x+y;
printf(“\nSum of %d %d is %d “,x,y,res);
}
void main()
{
int a,b;
printf("enter a,b");
scanf("%d%d",&a,&b);
sum(a,b); /* Function Call */
return 0;
}

Example: Function with return value without arguments.


/*program to find factorial of a given number using a function*/
#include<stdio.h>
int factorial()
{
printf(“\n Enter a number”);
scanf(“%d”,&x);
int i,f;
f=1;
for(i=1;i<=x;i++)
f=f*i;
return(f);
}
void main()
{
int n,fn;
fn=factorial(); /* Function Call */
printf("the factorial %d is%d\n",n,fn);
}

CSE, RIT Page 3


Example: Function without return value without arguments.

#include <stdio.h>
void sum()
{
int a,b,c;
printf(“enter two numbers “); scanf(“%d%d”,&a,&b);
c=a+b;
printf(“Sum is %d”,c); }

void main( )
{
sum(); /*------- function call */
}

Example: Write a program to find Largest Element in an array (using function)

/*program to find largest element from an array using a function*/


#include<stdio.h>
#include<conio.h>

int largest(x,m) int x[],m;


{
int i,l=0;
for (i=0;i<m;i++) if(x[i]>l)
l=x[i];
return (l);
}

void main()
{
int a[10],i,n,large;
clrscr();
printf("enter size" ); scanf("%d",&n);
for (i=0;i<n;i++)
{
printf("enter array element "); scanf("%d",&a[i]);
}
large=largest(a,n);
printf("the largest = %d\n",large);
getch();
}

Example: Write a program to sort an array of elements:

/*program to arrange array elements of a single dimensional array in sorted order using a
function*/
#include<stdio.h>
#include<conio.h>
sorting(a,n)
int a[],n;
{
int i,j,temp;
for (i=0;i<n-1;i++)
4|Page
for (j=0;j<n-i-1;j++)
if (a[j] > a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
void main()
{
int a[10],i,j,n,temp;
printf("enter size" ); scanf("%d",&n);
for (i=0;i<n;i++)
{
printf("enter array element "); scanf("%d",&a[i]);
}

sorting(a,n); /* function call */

printf("the sorted array elements are\n");


for (i=0;i<n;i++)
printf("%d\n",a[i]);
getch();
}

Call by value & call by reference

There are two ways in which we can pass arguments to the functions a) call by value and b) call by
reference.

A) Call by value:
In this type, the value of actual arguments are passed to the formal arguments and the operation is
done on the formal arguments. Any change in the formal arguments does not affect the actual
arguments. Both the formal and actual arguments are allocated memory separately. Hence when the
function is called by the call by value method, it does not affect the actual arguments.
Example:
main()
{
int x,y, interchange(int,int);
printf(“Enter values of x and y”);
scanf(“%d %d”,&x,&y);
interchange(x,y);
printf(“\n In main prg x and y values are %d %d”,x,y);
return 0;
}
void interchange(int a, int b)
{
int t;
t=a;
a=b;
b=t;
printf(“\n In the function x and y values are %d %d”,a,b);
}
Output:
Enter values of x and y 5 6
In the function x and y values are 6 5
5|Page
In main prg x and y values are 5 6.

Explanation:
In the above program we are passing values of actual parameters x and y to the function interchange().
The formal arguments a, and b of the function receives these values. These values are interchanges and
printed. When the control return to the main again we are printing the values of x, y . These are printed
as they read from the keyboard. The change done in the function is not affected actual arguments.

B) Call by reference:

In this type instead of passing values, address are passed as argument. Function operates on address.
Here the formal arguments are the pointers to the actual arguments. Only one storage location is used
here i.e for actual arguments only. Hence the changes made in the formal arguments will remain with
actual arguments also.

Example:
main()
{
int x,y, interchange(int*,int*);
printf(“Enter values of x and y”);
scanf(“%d %d”,&x,&y);
interchange(&x,&y);
printf(“\n In main prg x and y values are %d %d”,x,y);
return 0;
}

void interchange(int *a, int *b)


{
int t;
t=*a;
*a=*b;
*b=t;
printf(“\n In the function x and y values are %d %d”,*a,*b);
}
Output:

Enter values of x and y 5 6


In the function x and y values are 6 5
In main prg x and y values are 6 5.

Inter Function Communication in C


When a function gets executed in the program, the execution control is transferred from calling a
function to called function and executes function definition, and finally comes back to the calling
function. In this process, both calling and called functions have to communicate with each other to
exchange information. The process of exchanging information between calling and called functions is
called inter-function communication.
In C, the inter function communication is classified as follows...

 Downward Communication
 Upward Communication
 Bi-directional Communication

6|Page
Downward Communication
In this type of inter function communication, the data is transferred from calling function to called
function but not from called function to calling function. The functions with parameters and without
return value are considered under downward communication. In the case of downward
communication, the execution control jumps from calling function to called function along with
parameters and executes the function definition, and finally comes back to the calling function without
any return value. For example consider the following program.
Example Program
#include<stdio.h>
#include<conio.h>
void main(){
int num1, num2 ;
void addition(int, int) ; // function declaration
clrscr() ;
num1 = 10 ;
num2 = 20 ;

printf("\nBefore swap: num1 = %d, num2 = %d", num1, num2) ;


addition(num1, num2) ; // calling function

getch() ;
}
void addition(int a, int b) // called function
{

printf("SUM = %d", a+b) ;

Output:

7|Page
Upward Communication

In this type of inter-function communication, the data is transferred from called function to calling-

function but not from calling-function to called-function. The functions without parameters and with

return value are considered under upward communication. In the case of upward communication, the

execution control jumps from calling-function to called-function without parameters and executes the

function definition, and finally comes back to the calling function along with a return value. For
example, consider the following program.
Example Program
#include<stdio.h>
#include<conio.h>

void main(){
int result ;
int addition() ; // function declaration
clrscr() ;
result = addition() ; // calling function
printf("SUM = %d", result) ;
getch() ;
}
int addition() // called function
{
int num1, num2 ;
num1 = 10;
num2 = 20;
return (num1+num2) ;
}

Output:

8|Page
Bi - Directional Communication

In this type of inter-function communication, the data is transferred from calling-function to called

function and also from called function to calling-function. The functions with parameters and with

return value are considered under bi-directional communication. In the case of bi-directional

communication, the execution control jumps from calling-function to called function along with

parameters and executes the function definition and finally comes back to the calling function along
with a return value. For example, consider the following program...
Example Program
#include<stdio.h>
#include<conio.h>

void main(){
int num1, num2, result ;
int addition(int, int) ; // function declaration
clrscr() ;
num1 = 10 ;
num2 = 20 ;
result = addition(num1, num2) ; // calling function
printf("SUM = %d", result) ;
getch() ; }
int addition(int a, int b) // called function
{
return (a+b) ;
}

Output:

STANDARD FUNCTIONS

9|Page
The standard functions are built-in functions. In C programming language, the standard functions are
declared in header files and defined in .dll files. In simple words, the standard functions can be defined
as "the ready made functions defined by the system to make coding more easy". The standard
functions are also called as library functions or pre-defined functions.
In C when we use standard functions, we must include the respective header file
using #include statement. For example, the function printf() is defined in header
file stdio.h (Standard Input Output header file). When we use printf() in our program, we must
include stdio.h header file using #include<stdio.h> statement.
Some Of The Standard Functions In C Are Given Below.

Header Purpose Example


File Functions
stdio.h Provides functions to perform standard I/O operations printf(), scanf()

conio.h Provides functions to perform console I/O operations clrscr(), getch()

math.h Provides functions to perform mathematical operations sqrt(), pow()

string.h Provides functions to handle string data values strlen(), strcpy()

stdlib.h Provides functions to perform general functions calloc(), malloc()

time.h Provides functions to perform operations on time and date time(), localtime()

ctype.h Provides functions to perform - testing and mapping of character isalpha(),


data values islower()

PASSING ARRAY TO FUNCTIONS


In C programming, you can pass en entire array to functions. Example below shows how an array can
be passed to a function as an argument.

// Program to calculate the sum of array elements by passing to a function

#include <stdio.h>
float calculateSum(float age[]);

int main() {
float result, age[] = {23.4, 55, 22.6, 3, 40.5, 18};

// age array is passed to calculateSum()


result = calculateSum(age);
printf("Result = %.2f", result);
return 0;
}

10 | P a g e
float calculateSum(float age[]) {

float sum = 0.0;

for (int i = 0; i < 6; ++i) {


sum += age[i];
}

return sum;
}

Output

Result = 162.50

To pass an entire array to a function, only the name of the array is passed as an argument.

result = calculateSum(age);

However, notice the use of [] in the function definition.

float calculateSum(float age[]) {


... ..
}

This informs the compiler that you are passing a one-dimensional array to the function. In the above
example the array name is supplied as an argument but the size of the array is not supplied. We can
also pass the size of the array as an argument along with the array name.

Example: find sum of elements of an array by using functions.

#include<stdio.h>

int addition(int[],int);

void main()

int x[10],i,n,sum;

clrscr();

printf(“enter size of the array”);

scanf(“%d”,&n);

printf(“enter elements”):

for(i=0;i<n;i++)
11 | P a g e
scanf(“%d”,&x[i]);

sum=addition(x,n);

printf(“sum=%d”,sum);

getch();

int addition(int x[],int n)

int sum=0,i;

for(i=0;i<n;i++)

sum=sum+x[i];

return(sum);

Output:

Enter size of the array: 4

Enter elements: 10 20 30 40

Sum=100

NOTE: Similarly, we can pass a two dimensional array to a function as an argument. But, in 2
dimensional arrays, you need to use two subscripts during function declaration and definition.

RECURSION

 Recursion is a special case of process, where a function calls itself.

 A function is called recursive if a statement within the body of a function calls the same
function.

int factorial(x) int x;


{
if (x ==1) return(1);
else
return(x * factorial(x-1));
}

12 | P a g e
When writing recursive functions, you must have an if statement somewhere in the recursive
function to force the function to return without recursive call being executed. If you do not do this and
you call the function, you will fall in an indefinite loop, and will never return from the called function.

/*program to find factorial of a number using a Recursive function*/


#include<stdio.h>
#include<conio.h>
int factorial(x) int x;
{
if (x<=1) return(1);
else return(x*factorial(x-1));
}
void main()
{
int n,fn;

clrscr();

printf("enter n"); scanf("%d",&n);

fn=factorial(n); /* Function Call */

printf("the factorial of %d is %d\n",n , fn);


getch();
}
In case the value of n is 4, main() would call factorial() with 4 as its actual argument, and factorial()
will send back the computed value. But before sending the computed value, factorial() calls factorial()
and waits for a value to be returned.

factorial(4) returns 4*factorial(3) 4*6 = 24


factorial(3) returns 3*factorial(2) 3*2 = 6
factorial(2) returns 2*factorial(1) 2*1 = 2
factorial(1) returns 1 Backward Substitution

/* Program to find GCD of two numbers using a Recursive function */

#include<stdio.h>
#include<conio.h>
int gcd(int u,int v)
{
if (v==0) return(u);
else return(gcd(v,u%v));
}
int main()
{
int m,n,g;
clrscr();
printf("enter m and n");
scanf("%d%d",&m,&n);
g=gcd(m,n); /*---------- Function Call */
printf("the gcd of %d and %d is %d\n",m,n,g);
return 0;
}

13 | P a g e
/* Program to find nth Fibonacci number using a Recursive function*/
#include<stdio.h> #include
<math.h>
int fib(n)
int n;
{
if (n==1) return(0);
else
if (n==2) return(1);
else return(fib(n-1)+fib(n-2));
}
void main()
{
int n,f; clrscr();
printf("which term you want"); scanf("%d",&n);
f=fib(n);
printf("The %d th Fibonacci term is %d \n",n,f); getch();
}

SCOPE AND LIFETIME OF VARIABLES (STORAGE CLASSES)

Variables in C differ in behavior from those in most other languages.


A variable in C can have any one of the four storage classes.
1. Automatic variables.
2. External variables.
3. Static variables.
4. Register variables.

SCOPE: The scope of a variable determines over what part(s) of the program a variable is actually
available for use.

LIFETIME: Lifetime refers to the period during which a variable retains a given value during
execution of a program (alive).

A variable may also be broadly categorized depending on the place of their declaration as internal
(local) or external (global). Internal variables are those which are declared within a particular function,
while external variables are declared outside of any function.

1. AUTOMATIC VARIABLES:
Automatic variables are declared inside a function in which they are to be utilized. They are
created when the function is called and destroyed automatically when the function is exited; hence the
name automatic variables are also referred to as local or internal variables.
A variable declared inside a function without storage class specification is, by default, an automatic
variable. We may also use the keyword auto to declare automatic variables explicitly.
main( )
{
int num; auto int num;
- -
-} }
The value of automatic variable cannot be changed accidentally by what happens in some other
function in the program. This assures that we may declare and use the same variable name in different
functions in the same program without causing any confusion to the compiler.
void main( )

14 | P a g e
{
int m=1000;
function2( );
printf(“%d\n”,m);
}

function1( )
{
int m=10;
printf(“%d\n”,m);
}
Output
function2( ) 10
{
100
int m=100;
1000
function1( );

printf(“%d\n”,m);
}

A program with two sub programs function1( ) and function2( ) is shown. m is an automatic variable
and it is declared at the beginning of the each function. m is initialized to 10, 100, 1000 in function1,
function2 and main( ) respectively.
When executed, main( ) calls function2, which in turn calls function1. When main is active
m=1000, but when f2 is called the main‟s m is temporarily put on the shelf and the new local m=100
becomes active. Similarly when function1 is called both the previous values of m are put on the shelf
and the latest value of m=10 becomes active. As soon as function1 is finished, function2 takes over
again. As soon it is done, main takes over the output clearly. Shows that the value assigned to m is one
function does not effect its value in the other functions, and the local value of m is destroyed when its
leaves a function.

2. EXTERNAL VARIABLES:
Variables that are both alive and active through out the entire program are known as external
variables. They are also known as global variables. Unlike local variables, global variables can be
accessed by any function in the program. External variables are declared out side a function
Ex:
int a; int b;
main( );
{
-
-
}
Fun1()
{

}
Fun2()
{

}
The variables a and b are available for use in all the three functions. In case a local variable and global
variable have the same name, the local variable will have precedence over the global one in the
function where it is declared.
Once a variable has been declared as global, any function can use it and change its value. Then
subsequent functions can reference only that new value.
15 | P a g e
One other aspect of a global variable is that it is visible only from the point of declaration to the end of
the program. Consider a program segment as shown below.
void main()
{
y=5;
.
.}
int y;
fun1()
{
y=y+1; .
.
}
As far as main() is concerned, y is not defined. So, the compiler will issue an error message. Unlike
local variables global variables are initialized to zero by default.
In the above program segment, the main() can not access the variable y as it has been declared after
the main() function. Declaring the variable with the storage class extern can solve this problem.

main( )
{
extern int y;
-
-
}
function1( )
{
extern int y;
-
-
}
int y;

Although the variable y has been defined after both the functions, the external declaration of y inside
the functions informs the compiler that y is an integer type defined some where else in the program.

num=2; OUTPUT
printf(“num=%s\n”,num); num= 2
fun1(); num= 7
printf(“num=%s\n”,num); num=17
fun2();
printf(“num=%s\n”,num);

fun1()
{
num=num+5;
}
fun2()
{
} num=num+10;

Example 1) Global variable declaration before the functions


#include<stdio.h>
int n; /* Global Declaration */
16 | P a g e
main()
{
}

Example 2) Global variable declaration after the functions


#include<stdio.h>
main()
{
extern int num;
num=2;
OUTPUT
printf(“num=%s\n”,num); num= 2
fun1(); num= 7
printf(“num=%s\n”,num); num=17
fun2();
printf(“num=%s\n”,num);
}
fun1()
{
extern int num;
num=num+5;
}
fun2()
{
extern int num;
num=num+10;
}
int num; /* Global Declaration */

3. STATIC VARIABLES:
As the name suggests, the value of static variables persists until the end of the program. A
variable can be declared static using the key word static like
static int x; static
float y;
A static variable may be either an internal type or an external type, depending on the place of
declaration. Internal static variables are those which are declared inside a function. The scope of
internal static variables extends up to the end of the function, in which they are defined. Therefore,
internal static variables are similar to auto variables, except that they remains in existence (alive)
throughout the remainder of the program. Therefore internal static variables can be used to retain
values between function calls.
Example for static variable Example for Auto variable

void main( ) void main( )


{ {
int i; int i;
for(i=1; i<=3; i++) for(i=1; i<=3; i++)
fun( ); afun( );
} }
fun( ) afun( )
{ {
static int x=0; int x=0;
x=x+1; x=x+1;
printf(“x=%d\n”,x); printf(“x=%d\n”,x);
} }
out put out put
17 | P a g e
x=1 x=1
x=2 x=1
x=3 x=1

A static variable is initialized only once, when the program is compiled it is never initialized
again. During the first call to fun( ) function x is incremented to 1. Because x is static, this value
persists and therefore, the next call adds another 1 to x giving it a value of 2. The value of x
becomes 3 when the third call is made.

4. REGISTER VARIABLES:
We can tell the compiler that a variable should be kept in one of the machine‟s registers, instead of
keeping in the memory. Since a register access is much faster than a memory access, keeping the
frequently accessed variables in the register will lead to the faster execution.
register int count;
Most compilers allow only int or char variables to be placed in the register

TYPE QUALIFIERS

TYPES OF C TYPE QUALIFIERS:


There are two types of qualifiers available in C language. They are,

1. const
2. volatile
1. CONST KEYWORD:
 Constants are also like normal variables. But, only difference is, their values can‟t be modified
by the program once they are defined.
 They refer to fixed values. They are also called as literals.
 They may be belonging to any of the data type.
 Syntax:
const data_type variable_name; (or) const data_type *variable_name;
 Please refer C – Constants topic in this tutorial for more details on const keyword.
2. VOLATILE KEYWORD:
 When a variable is defined as volatile, the program may not change the value of the variable
explicitly.
 But, these variable values might keep on changing without any explicit assignment by the
program. These types of qualifiers are called volatile.
 For example, if global variable‟s address is passed to clock routine of the operating system to
store the system time, the value in this address keep on changing without any assignment by the
program. These variables are named as volatile variable.
 Syntax:
volatile data_type variable_name; (or) volatile data_type *variable_name;

POINTERS

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 you can use 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 * you used to declare a pointer is the same asterisk that you use
for multiplication. However, in this statement the asterisk is being used to designate a variable as a
pointer.
18 | P a g e
Pointers can be used to pass information back and forth between a function and its reference
point. In particular, pointers provide a way to return multiple data items from a function via function
arguments.
Pointers are also closely associated with arrays and therefore provide an alternative way to
access individual array elements. The computer memory is a sequential collection of storage cells.
Each cell commonly known as a byte, has a number called address associated with it.
Typically the addresses are numbered consecutively starting from zero. The last address
depends on memory size.

int num=50;
This statement instructs the system to find a location for the integer variable „num‟ and puts the value
50 in that location.

Let us assume that the system has chosen the address location 2000 for num.

printf(“num=%d address=%u\n”,num,&num);

Output:

num=50 address=2000

Declaring Pointer Variables

 Since addresses are numeric values, they can be stored in variables, just like any other kind of
data.
 Pointer variables must specify what kind of data they point to, i.e. the type of data for which they
hold the address. This becomes very important when the pointer variables are used.
 When declaring variables, the asterisk, *, indicates that a particular variable is a pointer type as
opposed to a basic type.
 So for example, in the following declaration:

int i, j, *iptr, k, *numPtr, *next;

variables i, j,and k are of type ( int ), and variables iptr, numPtr, and next are of type ( pointer to int )

Assigning Pointer Variables

Pointers can be assigned values as the program runs, just like any other variable type. For example:

int i = 42, j = 100;


int *p1 = NULL, *p2 = NULL; // pointers are initially point nowhere.

P1 = &i; // Now p1 points to i.

p2 = p1; // Now both pointers point to i. Note no & operator


p1 = &j; // p1 changed to point to j.

p2 = NULL; // p2 back to pointing nowhere.

Accessing a variable using Pointer - The Indirection Operator

 As discussed above, the asterisk,*, in a variable declaration statement indicates that a


particular variable is a pointer type.
19 | P a g e
 In executable statements, however, the asterisk is the indirection operator, and has a totally
different meaning.
 In particular, the indirection operator refers to the data pointed to by the pointer, as opposed to
the pointer itself. (i.e. the * in an executable statement says to follow the pointer to its
destination.)

For example:

int i, , j;
int *iptr = &i, *jptr = &j; // These * indicates variables of type ( pointer to int )

i = 42; // changes i to 42
*iptr = 100; // changes i from 42 to 100
j = *iptr; // Now j is 100 also

/* Note carefully the distinction between the following two lines */


*jptr = *iptr; // Equivalent to j = i. jptr and iptr still point to different places
jptr = iptr; // Makes jptr point to the same location as iptr. Both now point to i

Another example:

#include <stdio.h>
int main ()
{
int var = 20; /* variable declaration */
int *ip; /* pointer variable declaration */
ip = &var; /* store address of var in pointer variable*/
clrscr();
printf("Address of var variable: %u\n", &var ); /* address stored in pointer variable */
printf("Address stored in ip variable: %u\n", ip ); /* access the address using the pointer */
printf("Value of *ip variable: %d\n", *ip ); /* access value through pointer */
return 0;
}

Output:
Address of var variable: 65492
Address stored in ip variable: 65492
Value of *ip variable: 20
Hint:
In the above program…
ip is points to address of variable.
*ip is known as „value at pointer‟.

Pointer dereferencing

Once a pointer is declared, you can refer to the thing it points to, known as the target of the
pointer, by "dereferencing the pointer". To do this, use the unary * operator:

int * ptr; // ptr is now a pointer-to-int


// Notation:
// ptr refers to the pointer itself
// *ptr the dereferenced pointer -- refers now to the TARGET

20 | P a g e
Suppose that ptr is the above pointer. Suppose it stores the address 1234. Also suppose that the
integer stored at address 1234 has the value 99.

printf( "The pointer is: %u", ptr);// prints the pointer


printf "The target is: %d”, *ptr); // prints the target

// Output:
// The pointer is: 1234 // exact printout here may vary
// The target is: 99

Pointer Arithmetic

 There are a few very limit mathematical operations that may be performed on address data types,
i.e. pointer variables.
 Most commonly, integers may be added to or subtracted from addresses.
 Note that increment and decrement operations are really just special cases of addition and
subtraction.

In other words, if a pointer is incremented, it is actually increased sufficiently to point to the


next adjacent "thing" in memory, where "thing" corresponds to the type of data that the pointer is
declared as pointing to.

For example

int a[10], *p;


p=a;
p points to starting address of array a.
p++ points next element in array. p is increased by the size of int. In the same manner when p
is decreased it decreases by the size of int.

Combinations of * and ++

 *p++ accesses the thing pointed to by p and increments p


 (*p)++ accesses the thing pointed to by p and increments the thing pointed to by p
 *++p increments p first, and then accesses the thing pointed to by p
 ++*p increments the thing pointed to by p first, and then uses it in a larger expression.

Pointer to pointer
A pointer to a pointer is a form of multiple indirections, or a chain of pointers. Normally, a
pointer contains the address of a variable. When we define a pointer to a pointer, the first pointer
contains the address of the second pointer, which points to the location that contains the actual value
as shown below.

A variable that is a pointer to a pointer must be declared as such. This is done by placing an
additional asterisk in front of its name. For example, following is the declaration to declare a pointer to
a pointer of type int:

int **var;
int **var;

21 | P a g e
When a target value is indirectly pointed to by a pointer to a pointer, accessing that value
requires that the asterisk operator be applied twice, as is shown below in the example:

Example program:

#include <stdio.h>
void main ()
{
int var;
int *ptr;
int **pptr;

var = 3000;

/* take the address of var */


ptr = &var;

/* take the address of ptr using address of operator & */


pptr = &ptr;

/* take the value using pptr */


printf("Value of var = %d\n", var );
printf("Value available at *ptr = %d\n", *ptr );
printf("Value available at **pptr = %d\n", **pptr);
}
Output:

Value of var = 3000


Value available at *ptr = 3000
Value available at **pptr = 3000

Pointers and Arrays

(Pointers to Array Elements)

 A pointer may be made to point to an element of an array by use of the address operator(*):

int n[10], *iptr = NULL;


iptr = & nums[ 3 ]; // iptr now points to the fourth element
*iptr = 42;
Ex) Program to access elements of a single dimensional array using a pointer variable
/*-------------------------------------------------------------------------------------------------------*/
#include<stdio.h>
#include<conio.h>
void main()
{
static int a[5] = { 1,2,3,4,5 };
int i,*p;
clrscr();
printf("The array elements are (normal accessing)\n");
for(i=0;i<5;i++)
printf("%d is stored at %u\n" ,a[i], &a[i]);

p=a; /*..pointer initialization*/


printf("The array elements are (pointer accessing)\n");
for(i=0;i<5;i++)
22 | P a g e
printf("%d is stored at %u\n",*(p+i) , (p+i));
}

Output:
The array elements are (normal accessing) The array elements are (pointer accessing)
1 is stored at 404 1 is stored at 404
2 is stored at 406 2 is stored at 406
3 is stored at 408 3 is stored at 408
4 is stored at 410 4 is stored at 410
5 is stored at 412 5 is stored at 412

Ex) Program using pointers to sum of all elements stored in an array


/*-------------------------------------------------------------------------------------------------------*/
#include<stdio.h>
#include<conio.h>
void main()
{
int a[10],sum=0,i;
int *p;
float avg;
p=a; /*pointer assigning to base address of array i.e. to a[0] */
printf("\n Enter 10 numbers: ");
for(i=0;i<10;i++)
{
scanf("%d",p);
sum=sum+(*p);
p++;
}
avg=sum/10;
printf("\nSum is: %d & Average is: %f ",sum,avg);
getch();
}
Output:
Enter 10 numbers: 15
10 16
11 14
12 18
13 17
14 Sum is: 140 & Average is: 14.000000

Pointers and Character Strings


Note: there is no „string type‟ in „C language‟.
Strings are treated like „character arrays‟ and therefore they are declared and initialized as follows:

char str [5] = ”good” ;


The compiler automatically inserts the null character „\0‟ at the end of the string.
C supports an alternative method to create string using pointer variables of type char. Example:

char *str = “good” ;


This creates a string for the literal and then stores its address in the pointer variable str.
The pointer str now points to the first character of the string “good” as:

g o o d \0

23 | P a g e
str

We can also use the run-time assignment for giving values to a string pointer. Example

char * string1;
string1 = “good” ;
We can print the content of the string1 using either printf or puts function as follows:

printf(“%s”,string1);
puts(string1);
Note: although string1 is a pointer to the string, it is also the name of the string. Therefore, we do not
need to use indirection operator * here.

Ex) Program using pointers to determine the length of a character string.


/*------------------------------------------------------------------------------------------*/
#include<stdio.h>
#include<conio.h>
void main()
{
char *name;
char *cptr;
int length;
name="DELHI";
cptr=name;
clrscr();
printf("%s",name);
while(*cptr!='\0')
{
printf("\n%c is stored at %u\n",*cptr,cptr);
cptr++;
}
length=cptr-name;
printf("\nThe Length of string = %d\n",length);
getch();
}
D E L H I \0

Name(404) cptr(409)

Output:
DELHI H is stored at 407
D is stored at 404 I is stored at 408
E is stored at 405 The Length of string = 5
L is stored at 406

Arrays of Pointers

One important use of pointers is in handling of a table of strings. Consider the following array of
strings:
char name [3][25];

24 | P a g e
This says that the name is a table containing three names, each with a maximum length of 25
characters (including null character). The total storage requirements for the name table are 75 bytes
(3x25).

We know that rarely the individual strings will be of equal lengths. Therefore, instead of
making each row a fixed number of characters, we can make it a pointer to a string of varying length.
For example,
char *name[3]={“India”,“New Zealand”,”Australia”};
declares name to be an array of three pointers to characters, each pointer pointing to a particular name
as:
name[0] ------- India
name[1] ------- New Zealand
name[2] ------- Australia
this declaration allocates only 28 bytes, (75-28=47 bytes saving)
I n d i a \0
N e w z e a l a n d \0
A u s t r a l i a \0
Example program :
#include <stdio.h>
void main ()
{
int i;
char *name[3]={"India","New Zealand","Australia"};
for(i=0;i<=2;i++)
printf("%s\n",name[i]);
}
Output:
India
New Zealand
Australia

To access jth character in the ith name, we may write as

*(name[i]+j)

We can have arrays of pointers since pointers are variables.


Example 2:
#include <stdio.h>
void main()
{
char *p[3],s[10],r[10],t[10];
strcpy(s,"abc");
strcpy(r,"def");
strcpy(t,"wer");
p[0]=s;
p[1]=r;
25 | P a g e
p[2]=t;
printf("\n%s\n%s\n%s",p[0],p[1],p[2]);
}
Output:
abc
def
wer

In above example p is array of char pointers. Each pointer element is pointing one string. i.e
p[0] points to s, p[1] points to r and p[2] points to t. It is when you use array of pointers to deals with
strings.

Multidimensional arrays and pointers

We should think of multidimensional arrays in a different way in C:

A 2D array is really a 1D array, each of whose elements is itself an array

So we use the declaration like this

a[m][n] where a is 2D array with m rows and n columns.

Array elements are stored row by row. C needs to know how many columns in order that it can
jump from row to row in memory. Here is an example.

In the above figure, array is a pointer-to-pointer-to-int: at the first level, it points to a block of
pointers, one for each row.

That first-level pointer is the first one we allocate; it has nrows elements, with each element
big enough to hold a pointer-to-int, or int *. If we successfully allocate it, we then fill in the pointers
(all nrows of them) with a pointer (also obtained from malloc) to ncolumns number of ints, the storage
for that row of the array. If this isn't quite making sense, a picture should make everything clear:

Example program:

#include <stdlib.h>
#include <stdio.h>
main()
{
int **array; /* like array[][] & pointer-to-pointer-to-int */
int nrows,ncolumns,i,j;
clrscr();
printf("\nenter no of rows & columns:");
scanf("%d%d",&nrows,&ncolumns);
26 | P a g e
array = malloc(nrows * sizeof(int *)); /* Dynamically memory allocating to array*/

printf("Enter elements\n");
for(i=0;i<nrows;i++)
{
for(j=0;j<ncolumns;j++)
scanf("\n%d",&(*(*(array+i)+j)));
}
printf("output\n");
for(i=0;i<nrows;i++)
{ for(j=0;j<ncolumns;j++)
printf("\n%d", *(*(array+i)+j)); /* like array[i][j] */
}
getch();
}

Output:

27 | P a g e
Enter no of rows & columns :2
2
Enter elements
1
2
3
4
output

1
2
3
4

Pointers and Functions

Pointers as Function Arguments

Previously we pass values (call by value) to the function. Now using pointers we can
pass addresses (call by address) to the functions.

Ex) Write a function using pointers to exchange the values stored in two locations in memory.
/*------------------------------------------------------------------------------------------*/
#include<stdio.h>
#include<conio.h>
void exchange(int *,int *); /* prototype */
void main()
{
int x,y;
x=100;
y=200;
printf("before exchange : x=%d y=%d \n\n",x,y);
exchange(&x,&y); /* function call & we passing addresses here*/
printf("after exchange : x=%d y=%d \n\n",x,y);
getch();
}
void exchange(int *a,int *b) /* pointers as function arguments*/
{
int t;
t=*a;
*a=*b;
*b=t;
}

Om Prakash Samantray, CSE, RIT Page 28


Output:
before exchange : x=100 y=200
after exchange : x=200 y=100

Function Returning Pointers

We have seen so far that a function can return a single value by its name or return
multiple values through pointer parameters. Since pointers are a data type in C, we can also force
a function to return a pointer to the calling function. Consider the following code:

#include<stdio.h>
#include<conio.h>
void *large(int *,int *); /* prototype */
void main()
{
int x,y;
int *p;
x=100;
y=20;
p=large(&x,&y); /*assigning return address(from function large() function) to
pointer p */
printf("%d\n",*p);
getch();
}
void *large(int *a,int *b)
{
if(*a>*b)
return(a); /* returning address of a*/
else
return(b); /* returning address of b */
}
Output:
before exchange : x=100 y=200
after exchange : x=200 y=100

Pointers to Functions

A function, like a variable, has a type and an address location in memory. It is therefore,
possible to declare a pointer to a function, which can then be used as an argument in another
function. A pointer to a function is declared as follows:

type (*ptr) ();

Om Prakash Samantray, CSE, RIT Page 29


This tells the compiler that ptr is a pointer to a function, which returns type value.

/*calling a function through „function pointer‟ */


#include<stdio.h>
#include<conio.h>
int add(int,int); /* prototype */
int sub(int,int); /* prototype */
void main()
{
int (*fp)(); /*pointer fp to function */
int x;
fp=add; /* initially pointer points to add() function */
x=(*fp)(2,3); /* calling function add() through pointer */
printf("\n sum is %d\n\n",x);
printf("\n The sum is %d\n\n",x);
fp=sub; /* now pointer points to sub() function */
x=(*fp)(5,2); /* calling function sub() through pointer */
printf("The sub is %d",x);
getch();
}
int add(int a,int b)
{
int c=a+b;
return c;
}

int sub(int a,int b)


{
return a-b;
}
Output:
The sum is 5
The sub is 3

Constant Pointers

Let‟s first understand what a constant pointer is. A constant pointer is a pointer that
cannot change the address its holding. In other words, we can say that once a constant pointer
points to a variable then it cannot point to any other variable.

A constant pointer is declared as follows:


Om Prakash Samantray, CSE, RIT Page 30
Syntax:

Pointer_type * const pointer_name;

An example declaration would look like :

int * const ptr;

Lets take a small code to illustrate these type of pointers :

#include<stdio.h>

int main(void)
{
int var1 = 0, var2 = 0;
int *const ptr = &var1;
ptr = &var2;
printf("%d\n", *ptr);

return 0;
}

In the above example :

 We declared two variables var1 and var2


 A constant pointer „ptr‟ was declared and made to point var1
 Next, ptr is made to point var2.
 Finally, we try to print the value ptr is pointing to.

So, in a nutshell, we assigned an address to a constant pointer and then tried to change the
address by assigning the address of some other variable to the same constant pointer.

Lets now compile the program :

$ gcc -Wall constptr.c -o constptr


constptr.c: In function „main‟:
constptr.c:7: error: assignment of read-only variable „ptr‟

So we see that while compiling the compiler complains about „ptr‟ being a read only variable.
This means that we cannot change the value ptr holds. Hence we conclude that a constant pointer
which points to a variable cannot be made to point to any other variable.

Om Prakash Samantray, CSE, RIT Page 31


Pointer to Constant

As evident from the name, a pointer through which one cannot change the value of
variable it points is known as a pointer to constant. These type of pointers can change the
address they point to but cannot change the value kept at those address.

A pointer to constant is defined as :

Syntax:

const pointer_type* pointer_name;

An example of definition could be:

const int* ptr;

Lets take a small code to illustrate a pointer to a constant:

#include<stdio.h>

int main(void)
{
int var1 = 0;
const int* ptr = &var1;
*ptr = 1;
printf("%d\n", *ptr);
return 0;
}

In the code above :

 We defined a variable var1 with value 0


 we defined a pointer to a constant which points to variable var1
 Now, through this pointer we tried to change the value of var1
 Used printf to print the new value.

Now, when the above program is compiled :

$ gcc -Wall constptr.c -o constptr


constptr.c: In function „main‟:
constptr.c:7: error: assignment of read-only location „*ptr‟

So we see that the compiler complains about „*ptr‟ being read-only. This means that we cannot
change the value using pointer „ptr‟ since it is defined a pointer to a constant.

Om Prakash Samantray, CSE, RIT Page 32


Constant Pointer to a Constant

If you have understood the above two types then this one is very easy to understand as its
a mixture of the above two types of pointers. A constant pointer to constant is a pointer that can
neither change the address its pointing to and nor it can change the value kept at that address.

A constant pointer to constant is defined as :

const <type of pointer>* const <name of pointer>

for example :

const int* const ptr;

Lets look at a piece of code to understand this :

#include<stdio.h>

int main(void)
{
int var1 = 0,var2 = 0;
const int* const ptr = &var1;
*ptr = 1;
ptr = &var2;
printf("%d\n", *ptr);
return 0;
}

In the code above :

 We declared two variables var1 and var2.


 We declared a constant pointer to a constant and made it to point to var1
 Now in the next two lines we tried to change the address and value pointed by the
pointer.

When the code was compiled :

$ gcc -Wall constptr.c -o constptr


constptr.c: In function „main‟:
constptr.c:7: error: assignment of read-only location „*ptr‟
constptr.c:8: error: assignment of read-only variable „ptr‟

So we see that the compiler complained about both the value and address being changed. Hence
we conclude that a constant pointer to a constant cannot change the address and value pointed by
it.

Om Prakash Samantray, CSE, RIT Page 33


No Pointer to Constant Constant Pointers
*ptr = 20 Statement is Invalid in Pointer to *ptr = 20 is Absolutely Valid in Constant
1
Constant i.e Assigning Value is Illegal Pointers i.e Assigning Value is Perfectly legal
ptr ++ Statement is Valid in Pointer to ptr ++ Statement is invalid in Constant
2
Constant Pointers
Pointer Can be Incremented and Pointer Cannot be Incremented and
3
Decremented Decremented
4 Pointer is Pointing to Constant Data Object Constant Pointer is Pointing to Data Objects
5 Declaration : const int *ptr ; Declaration : int * const ptr ;

Allocating memory

There are two ways that memory gets allocated for data storage:

1. Compile Time (or static) Allocation


o Memory for named variables is allocated by the compiler
o Exact size and type of storage must be known at compile time
o For standard array declarations, this is why the size has to be constant
2. Dynamic Memory Allocation
o Memory allocated "on the fly" during run time
o dynamically allocated space usually placed in a program segment known as the
heap or the free store
o Exact amount of space or number of items does not have to be known by the
compiler in advance.
o For dynamic memory allocation, pointers are crucial

Function Use of Function


malloc() Allocates requested size of bytes and returns a pointer first byte of allocated space
Allocates space for an array elements, initializes to zero and then returns a pointer to
calloc()
memory
free() De-llocate the previously allocated space
realloc() Change the size of previously allocated space

Dynamic memory management functions:

Dynamic memory allocation is the practice of assigning memory locations to variables


during execution of the program by explicit request of the programmer. Dynamic allocation is a
unique feature to C (amongst high level languages). It enables us to create data types and
structures of any size and length to suit our programs need within the program.

Om Prakash Samantray, CSE, RIT Page 34


For example, for arrays, dynamic memory allocation eliminates the need to determine
the size of the array at declaration time. Dynamically allocated memory is freed when we are not
using it.
The functions malloc (), realloc (), calloc () and free (), the Library functions stdlib.h, malloc.h or
are responsible for this task.
The C programming language provides several functions for memory allocation and
management. These functions can be found in the<stdlib.h> header file.
S.N. Function and Description
void *calloc(int num, int size);
1
This function allocates an array of num elements each of which size in bytes will be size.

void free(void *address);


2
This function release a block of memory block specified by address.

void *malloc(int num);


3
This function allocates an array of num bytes and leave them initialized.

void *realloc(void *address, int newsize);


4
This function re-allocates memory extending it upto newsize.
malloc()

The malloc() function dynamically allocates memory when required. This function
allocates „size‟ byte of memory and returns a pointer to the first byte or NULL if there is some
kind of error
Format is as follows.
void * malloc (size_t size);

Specifies in bytes the size of the area you want to reserve the argument. It returns the
address as the return value of the dynamically allocated area. In addition, returns NULL if it fails
to secure the area. The failure to ensure that the situation is usually that is out of memory.
The return type is of type void *, also receive the address of any type. The fact is used as
follows.
double * p = (double *) malloc (sizeof (double));
Example:

int * p;
p = (int *) malloc (sizeof (int));
* p = 5;

Program

Om Prakash Samantray, CSE, RIT Page 35


#include <stdio.h> #include <conio.h>
#include <stdlib.h>
void main()
{
int n,i,*ptr,sum=0;
printf("Enter number of elements: ");
scanf("%d",&n);
ptr=(int*)malloc(n*sizeof(int)); /*memory allocated using malloc*/
if(ptr==NULL)
{
printf("Error! memory not allocated.");
exit(0);
}
printf("Enter elements of array: ");
for(i=0;i<n;++i)
{
scanf("%d",ptr+i);
sum=sum+*(ptr+i); /*sum+=*(ptr+i);*/
}
printf("Sum=%d",sum);
free(ptr);
getch();
}
calloc()

The calloc function is used to allocate storage to a variable while the program is running.
This library function is invoked by writing calloc(num,size).This function takes two arguments
that specify the number of elements to be reserved, and the size of each element in bytes and it
allocates memory block equivalent to num * size . The function returns a pointer to the
beginning of the allocated storage area in memory. The important difference between malloc and
calloc function is that calloc initializes all bytes in the allocation block to zero and the allocated
memory may/may not be contiguous.
calloc function is used to reserve space for dynamic arrays. Has the following form.

void * calloc (size_t n, size_t size);

Number of elements in the first argument specifies the size in bytes of one element to the second
argument. A successful partitioning, that address is returned, NULL is returned on failure.

Om Prakash Samantray, CSE, RIT Page 36


For example, an int array of 10 elements can be allocated as follows.
int * array = (int *) calloc (10, sizeof (int));
Note that this function can also malloc, written as follows.
int * array = (int *) malloc (sizeof (int) * 10);

Program ……refer in notes

realloc()

With the function realloc, you can change the size of the allocated area once. Has the
following form.
void * realloc (void * ptr, size_t size);

The first argument specifies the address of an area that is currently allocated to the size in
bytes of the modified second argument. Change the size, the return value is returned in re-
allocated address space. Otherwise it returns NULL.
Size may be smaller but larger than the original. If you have small, reduced what was
written in part will be inaccessible. If you increase the portion of the region will remain an
indefinite increase.
The address of the source address changed, but the same could possibly be different, even if the
different areas of the old style, because it is automatically released in the function realloc, for the
older areas it is not necessary to call the free function.
However, if the function fails and returns NULL, realloc, the older area is to remain still
valid. Therefore, the first pointer argument of the function realloc, both can be NULL pointer
return value is not returned.

Example program:

int main (void)


{
int * p1, * p2;
p1 = (int *) calloc (5, sizeof (int)); /* number of elements in an array of type 5 int */
p2 = (int *) realloc (p1, sizeof (int)); * / re-acquire the space of one type / * int
if (p2 == NULL) * / check if successful * /
{
free (p1); / *, the region remains valid since the original to free myself * /
Om Prakash Samantray, CSE, RIT Page 37
return 0;
}
p1 = NULL;
free (p2);
return 0;
}
The realloc function is a very feature-rich functions.

free()

Free function is used to release the reserved area .It has also been declared in stdlib.h,
which has the following form.
void free (void * ptr);
The argument specifies the address of a dynamically allocated area. You can then free up the
space.
Example:
int * p;
p = (int *) malloc (sizeof (int));
* p = 150;
printf ("% d \ n", * p);
free (p)

Command line arguments:

It is possible to pass some values from the command line to your C programs when they
are executed. These values are called command line arguments and many times they are
important for your program especially when you want to control your program from outside
instead of hard coding those values inside the code.
The command line arguments are handled using main() function arguments
where argc refers to the number of arguments passed, and argv[] is a pointer array which points
to each argument passed to the program. Argv is called as argument vector and argc is called as
argument counter.
Following is a simple example which checks if there is any argument supplied from the
command line and take action accordingly:

#include <stdio.h>

int main( int argc, char *argv[] )


{

Om Prakash Samantray, CSE, RIT Page 38


if( argc == 2 )
{
printf("The argument supplied is %s\n", argv[1]);
}
else if( argc > 2 )
{
printf("Too many arguments supplied.\n");
}
else
{
printf("One argument expected.\n");
}
}
When the above code is compiled and executed with a single argument, it produces the following
result.

Output:
$./a.out testing
The argument supplied is testing
When the above code is compiled and executed with a two arguments, it produces the following
result.

$./a.out testing1 testing2


Too many arguments supplied.
When the above code is compiled and executed without passing any argument, it produces the
following result.

$./a.out
One argument expected

argv[0] holds the name of the program itself and argv[1] is a pointer to the first command line
argument supplied, and *argv[n] is the last argument. If no arguments are supplied, argc will be
one, otherwise and if you pass one argument then argc is set at 2.

Om Prakash Samantray, CSE, RIT Page 39

You might also like