Download as pdf or txt
Download as pdf or txt
You are on page 1of 9

C & DS for I MCA Unit-4 VVIT

Pointers
Pointer is one of the striking features of C. It is the strongest and at the same time
dangerous feature in C. Pointers are used to increase efficiency. They improve the accessibility
& provide support for dynamic memory allocation. They add power and flexibility to a C
program.

A pointer is a variable, which holds the address of another variable. In fact pointer can
hold memory address of any object in the C program such as variable (of any type) an array or a
structure. In some other way, Pointers are one of the derived data types in C.

Memory organization:

Memory is sequential collection of storage cells and each cell is known as 1 Byte and has
number associated called Address. The address values typically vary from 0 to n-1, n being the
size of the memory in Bytes (capacity of the memory). Therefore the address values for a 64KB
RAM will vary from 0 to 65535. The pointers are used to store these values. Since all address
values are of type unsigned int, the format specifier “%u” is used for displaying a pointer
(address value). Therefore any kind of pointer is allocated only 2 Bytes of memory.

Pointer Declaration:

In order to declare & use a pointer variable, two operators are required. They are address
of (&) operator and indirection operator (*). The general form follows:

data_type *ptr_name;

The above declaration says the compiler that ptr_name is a pointer that stores the address another
variable which is of type the “data_type”. No matter ever is the data_type the compiler just
assigned 2B of memory since ptr_name just stores the address value (unsigned int).

v p
Eg:
int v = 53; 53 5002
int *p;
p = &v; // address of k is assigned to p. 5002 8097
printf(“v= %d

Note: Here p holds the address of v, to get address of v we can use address of operator (&v) has
again its own address. Moreover, an address is always an unsigned integer value. So it occupies
2 bytes. To display an unsigned integer value, use %u as its format specifier.

Staff: Janaki Ram and Krishna Prasad Dept of IT and CSE Page:1
C & DS for I MCA Unit-4 VVIT

char ch = ‘x’; float f = 78.89f; double d = 89.89898;


char *p; float *x; double *k;
p = &ch; x = &f; k = & d;

From the above example, user can understand that to hold the address of integer value, an
integer pointer is required & to hold a character value address, a character pointer is required and
so is the case with the other data types too.

Eg: 1.

#include<stdio.h>
#include<conio.h>
void main()
{
int *p;
int k = 10;
p = &k;
(*p)++; // through ‘p’ the value of k is incremented by 1.
printf(“%d %d”,a *p);
}
2.

#include<stdio.h>
#include<conio.h>
void swap(int *,int *);
void main()
{
int a=10,b=20;
printf(“\n Before Interchange…\n”);
printf(“%d %d”, a,b);
swap(&a, &b); // function with call by address or reference
printf(“\n After Interchange…\n”);
printf(“%d %d”, a,b);
}
void swap(int *p,int *q)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}

Staff: Janaki Ram and Krishna Prasad Dept of IT and CSE Page:2
C & DS for I MCA Unit-4 VVIT

Pointer Expressions:
The values of variables can be accessed through its pointer by using indirection operator
(*). Therefore the operation that we perform on normal variables can be performed when they
are accessed though pointer.
Eg:
int x, y, z;
int *p1,*p2;
p1=&x;
p2=&y;
//Now we have addresses of variables x and y in p1 and p2 and therefore values of x and y can be given
as *p1 and *p2.
z=*p1+*p2; //this is equivalent to z=x+y;
z=*p1 / *p2; //this is equivalent to z=x/y; notice the space given between / and *p2.

Note: while performing division in pointer expression, care should be taken that space is given
between division operator (/) and indirection operator (*) so that the compiler does not
understand it as a beginning of a multiline comment (/*).

Invalid Usage of Pointers:

In general the address of a variable is stored in a pointer that is declared using the data
type same as that of the variable. In other words the data type used to declare the variable and the
pointer should be same.

The complier does not throw an error when the data types are mismatched. This is
because the compiler sees all pointers as unsigned integer and so the address of float variable can
be stored in an int type pointer.

Eg: int *p;

float f;

p=&f; //wrong assignment. This allowed by the compiler as it see all pointers as unsigned int.

//But this is an improper assignment.

Advantages of pointer:

 Pointers provide efficient way of handling arrays. Use of pointer arrays for strings saves
memory when the different strings of different lengths.
 Pointers can be used to (indirectly) return multiple values from a function via function
arguments (call by reference).
 Pointers permit references to functions and thereby facilitating passing of functions as
arguments to other function.

Staff: Janaki Ram and Krishna Prasad Dept of IT and CSE Page:3
C & DS for I MCA Unit-4 VVIT

 Pointers allow C to support dynamic memory allocation and this allows this allows
manipulation of dynamic data structures such as stacks, queues, linked lists and trees.
 Increase the execution speed and thereby reduce the execution time.

Disadvantages:

 As the pointer directly deal with the address locations in the system memory, improper
handling of pointers can cause serious problems to the system.
 If a pointer is arbitrarily assigned an address value which actually is storing the address
of some other program, any change done to pointer value can affect the working of other
program and my sometimes crash the application.
 Therefore at most care should be taken while coding with pointers.

Address Arithmetic (Pointer Operations):


There are some limited operations that can be performed on pointers (addresses). In fact
we are only allowed to use increment/decrement and addition/subtraction of integer value.
When the pointer is incremented (p++) the address value is incremented by length of the data
type that it points to. This length is called the scale factor.
The length of the data type is given in the number of bytes it occupies in the memory. In general
on a 16 bit word length computer, the following is list of length of various data types:
char 1 byte
int 2 bytes
float 4 bytes
double 8 bytes
long int 4 bytes
short int 1 byte, etc

The address value in pointer is also decremented by scale factor when decrement operator is used
(p--).
When an integer n is added/subtracted to/from a pointer then the address value is
incremented/decremented by n times the scale factor.
Eg:
#include<stdio.h>
void main()
{
int x,*p;
float f, *fp;
clrscr();
p=&x; //let's assume the address of x is 4000
fp=&f; //let's assume the address of f is 5000

Staff: Janaki Ram and Krishna Prasad Dept of IT and CSE Page:4
C & DS for I MCA Unit-4 VVIT

printf("p=%u, p+1=%u, p+4=%u\n\n",p,p+1,p+4);


printf("fp=%u, fp+1=%u, fp+4=%u\n\n",fp,fp+1,fp+4);
getch();
}
Output:

4000, 4002, 4008


5000, 5004, 5016

Rules of Pointer Operations:

1. A pointer variable can be assigned the address of another variable which is of same type.
2. A pointer variable cannot be assigned an address of another variable which is declared
with a different data type. (refer to invalid use of pointer above)
3. A pointer variable can be assigned the value of another pointer variable.
4. A pointer can be initialized to NULL or zero value.
5. A pointer variable can be pre-fixed or post-fixed with increment or decrement operators.
6. An integer value may be added or subtracted from a pointer variable.
7. When two pointers point to the objects of the same data types, they can be compared
using relational operators.
8. When two pointers point to the same array, one pointer variable can be substracted from
another. (This is illustrated in Lab Exercise 7 a).
9. A pointer cannot be multiplied by a constant.
10. Two Pointers cannot be added.
11. A value cannot be assigned to an arbitrary address (i.e &x= 80; is illegal).

Pointer to Pointers:

Since pointers are also variables, the addresses of pointers can also be stored in another
variable which is called as pointer to pointer. A chain of pointers can be formed to any extent.
Eg:
int x,*p1,**p2;
p1=&x;
p2=&p1;
Here p1 stores the address of x and p2 stores the address of p1. This is called as multi-
indirections. &x, p1, *p2 gives the address of x and x, *p1, **p2 gives the value of x.

Pointers and Arrays:

Pointers concept can be applied to arrays too. All elements of array are stored in
continuous memory locations. Usually an array name holds a base address in memory. Hence a
pointer can hold the base address to access the array elements. Once the base address is found, it

Staff: Janaki Ram and Krishna Prasad Dept of IT and CSE Page:5
C & DS for I MCA Unit-4 VVIT

becomes easy to access remaining elements in the list. The following program illustrates the
same.
#include<stdio.h>
void increment(int *, int);
void main()
{
int a[5] = {11, 12, 13, 14, 15};
increment(a, 5);
for(i=0;i<5;i++)
printf(“%4d”,a[i]);
}

void increment(int *p, int n)


{
int i;
for(i=0;i<n;i++)
{
*p = *p+4;
p++;
}
}
Output: - 15 16 17 18 19

In the function increment each of the elements in the array are accessed and are
incremented by 4 each. Each element in array is accessed by incrementing the pointer.

In case of a 2-dimentional array, the name of the array will be a pointer to pointer.
int a[2][3];
For the above 2-D array, “a” will be holding the address of the first row and *a will be holding
the address of the first element in the first row. Therefore to access a value in a 2-D array by
using pointers, we first need get the address of the first element of in the corresponding row and
move to corresponding column required. The following are the expressions that can be used
along with their meanings.

a  pointer to first row.


a+i  pointer to ith row.
*(a+i)  pointer to first element of ith row.
*(a+i)+j  pointer to the jth element of ith row.
*(*(a+i)+j)  value of the element in jth column of ith row.

Staff: Janaki Ram and Krishna Prasad Dept of IT and CSE Page:6
C & DS for I MCA Unit-4 VVIT

Call by reference:

In general, when a function is called the actual arguments (values of the variables) are
sent as parameters. This is called “call by value” (please refer to previous unit notes for more
details of call by value). Alternatively, the addresses of the variables can also be sent to as
argument to the function when it is called. This is called “call by reference”.

To achieve call by reference, the function needs to be defined with a parameter list
containing pointer in it because only pointer can hold addresses of the other variables. While
calling the function the addresses of the variables can be sent using the address of (&) operator
or the pointers which are already holding their addresses.

Since the actual addresses are sent as the argument to the called function, any change to
the values of the argument in the called function will reflect the same in calling function. By
making use of this, a function can indirectly return multiple values which is not possible with the
return statement. The called function can change the values of the arguments to the values that
it wants to return and the calling function can accesses them directly as the arguments are the
addresses of its own variables.

Apart from this it can have the traditional return statement which can return one value.
Therefore a function which is not of void type and is having n pointers in its parameter list can
actually return n+ 1 value.

Eg:
void main()
{
int x=9, y=3,z=0;
printf(“Before function call: x=%d y=%d z=%d”, x,y,z);
z=func(&x, &y); //func is called by reference of the variables x and y
printf(“\nAfter function call: x=%d y=%d z=%d”, x,y,z);
}
func(int *a, int *b)
{
*a+=4; //these changes will affect the values of x and y as a and b hold their addresses of x,y
*b=78;
return (*b-*a); //this return value is assigned to z
}
Output:
Before function call: x=9, y=3, z=0
After function call: x=13, y=78, z=65

Staff: Janaki Ram and Krishna Prasad Dept of IT and CSE Page:7
C & DS for I MCA Unit-4 VVIT

Dynamic Memory Management:

In general when the variables or simple arrays are declared, memory is assigned to them
by the compiler before executing the program. This is called static allocation of memory.
Consider the below array:
float fa[20];
Here we mentioned the size of the array as 20, the complier allocated 20 memory locations each
of size 4 bytes. This memory which is statically allocated to array cannot be changed while the
program is running. It cannot be either decreased or increased. This may lead to wastage of
memory when elements stored less than 20 in number. It also restricts us to store a maximum of
20 elements.
C allows us to create memory dynamically during the execution of the program. It
provides a set of functions for dynamic memory management. They are:
 malloc()
 calloc()
 realloc()

malloc() is used to create a single memory location dynamically. The size of the memory
location is being sent as a argument. The function malloc() returns the address of the memor
created.
General Form:
data_type *p; //pointer of type data_type
p=(data_type*)malloc(sizeof(data_type)); //memory is created and address is stored in the pointer

The address returned by malloc should be type casted into corresponding pointer type.
To specify the size of memory location we use sizeof operator so that it works on different
system with different word length (16bit or 32 bit or so).
The initial value stored in the new memory created by malloc() is unpredictable.

calloc() is used to create a collection of memory locations dynamically. This function takes 2
arguments, first being the number of memory locations needed and second one is the size of each
memory location. The value in memory created is initialized to zero or NULL depending on the
data type.
General Form:
data_type *p;
p=(data_type*)calloc(n, sizeof(data_type));

The above statement creates n memory locations can store data of type data_type and return the
address of first memory location. Therefore subsequent memory locations can be accessed by
incrementing the pointer p.

Staff: Janaki Ram and Krishna Prasad Dept of IT and CSE Page:8
C & DS for I MCA Unit-4 VVIT

realloc() – used to adjusts the size of the memory location which is already created. In normal
cases, this function increases/decreases the size of memory without changing the address. While
adjusting the size, if needs more memory and is not available at the current address then it
changes the address and returns the new address (after allocation the memory).
This function needs two arguments, first being the pointer to memory previously created,
second should be new size required for the memory location.

General form:

p=(data_type*)malloc(sizeof(data_type)); //memory is created here


p=(data_type*)realloc(p,sizeof(data_type)+2); //memory is resized here and stored in same pointer

Note: All the three function discussed above are defined in alloc.h and it need to be included
while coding.

Eg:
#include<stdio.h>
#include<alloc.h>
void main()
{
double *p,sum;
int i,n;
clrscr();
puts("Enter the number of values:");
scanf("%d",&n);
p=(double*)calloc(n,sizeof(double)); //use of calloc function
for(i=0;i<n;i++)
{
printf("Enter the value of %d element: ",i+1);
scanf("%lf",p+i);
sum+=*(p+i);
}
printf("\n\nThe sum of all given numbers is %lf",sum);
getch();
}

Staff: Janaki Ram and Krishna Prasad Dept of IT and CSE Page:9

You might also like