INTRODUCTION
If Varun wants the address of Shreya, which is known to Druva, he would ask
Druva. Thus Druva by giving the address is pointing to the place where Shreya is
staying. We can thus call Druva as a pointer. The concept of pointers is some what
similar in programming. Similarly the concept of pointers is very useful in
programming.
Any variable, which is declared and initialized, has three things associated
with it
All the three things are equally important. The name of a variable, which
represents the memory location, is used to output the value stored in the variable
and the address of the variable is used to input a value to the variable.
Address
Figure 1 Components associated with a variable
We have always used variables to store values, however a variable can also be
used to store the address of another variable such variables are termed as pointer
variables. Thus a pointer is a variable, which can contain the address of another variable.
Definition
Program 1 : A C program to show the creation of a pointer variable.
#include <stdio.h>
main( )
{
int num=5;
int *ptr;
ptr = #
of the variable num=%u\ &num);
of the variable num =%d\
present in the pointer variable ptr=%u\
}
OUTPUT
Observing the program closely highlights the following points:
POINTER DECLARATION
We have already seen the pointer and its usage. In this section we try to
understand all the concepts clearly. A pointer is a variable that contains the address
of the memory location of another variable. To create a pointer variable we use the
syntax as shown below. First we have to specify the type of data stored in the location
identified by the pointer. Then a variable is created along with an asterisk. The
asterisk tells the compiler that you are creating a pointer variable. Finally, you give
the name of the variable.
Variable type being pointedto pointer variable name
€
A asterisk denotes apointer
POINTER OPERATOR
A pointer operator is used to classify a variable as a pointer and not as a
normal variable. Pointer variables can only store the address of another memory
location, while a normal variable can only store a value and not an address. The
classification is done by representing the variable with a combination of *(asterisk)
with the variable name.
Example 1 : int *ptr;
The declaration above creates a pointer-type variable, named ptr that will
contain the memory address of an integer type variable. Similarly the instruction
float *fees;
Creates a pointer named fees that will contain the memory address of a float
variable.
The base type of the pointer defines which type of variables the pointer is
pointing to. Technically, any type of operator can point anywhere in memory. All
pointer arithmetic is done relative to its base type. So it is important to declare the
pointers correctly. The lengths of various data types are as follows:
Program2:A C program to show the amount of space required to store variables.
#include<stdio.h>
main()
{
int a=5;
char b=
float c=17.53;
of integer=%d Amountofspace=%ubytes\
Amountofspace=%ubytes\
offloat=%f Amountofspace=%ubytes\
}
OUTPUT
The number of bytes to be required to store particular data items will vary
from machine to machine. The program above will help the user to find this out.
ADDRESS OPERATOR
Once we declare a pointer variable, we must make it to point to something.
We can do this by assigning to the pointer the address of the variable you want to
point to as in:
This places the memory address of the variable num into the pointer variable
ptr. If num is stored in memory 1765 address, then the variable ptr has the value
1765. The figure below highlights the situation discussed above.
Figure 2 Allocation of address to pointer variable
Program 3 : To illustrate pointer declaration.
#include<stdio.h>
main()
{
int *ptr; /* pointerto aninteger */
int num;
num = 45;
ptr=#
\
\ *(&num));
\
}
OUTPUT
We will get the same result by assigning the address of num to a regular (non
pointer) variable. The benefits is that we can also refer to the pointer variable as *ptr.
The asterisk tells the compiler that we are interested in the contents of the memory
location stored in the pointer. We are not interested in the value 1765, but in the
value stored in that memory location. While the value of ptr is 1765 the value of num
is 45.
NOTE
ptr = 1765;
ptr = #
*ptr = 45;
ce the pointer contains the address 1765, the value 45 is placed in that
memory location. And since this is the location of the variable num, the value of num
is also becomes 45. This shows how we can change the value of a variable indirectly
using a pointer and the indirection operator.
Program 4: Todefine three pointer variables for character, integer and float and
display the contents of the variable and their addresses.
#include<stdio.h>
main()
{
int int_var,*int_ptr;
float float_var,*float_ptr;
char char_var,*char_ptr;
int_var=123;
float_var=12.34;
int_ptr=&int_var;
float_ptr=&float_var;
char_ptr=&char_var;
\
\
\
}
POINTER EXPRESSIONS AND POINTER ARITHMETIC
Pointers are variables. Their values are not integers but addresses. Addresses
can be displayed as unsigned integers. Whenever we add a value to a pointer
variable the conversion specifier causes the pointer to be incremented, but not by
the value 1 but by a value which identifies the next consecutive location.
For example if n is an integer and the system stores integer in two bytes then
the address of n would occupy two consecutive bytes say the addresses 17500 and
17501. The code below shows what would happen when we perform an increment
operation with a pointer.
Example 2 : The following code illustrate the use of pointers in arithmetic
operation.
int n, *p;
n = 9;
p = &n;
p++;
\ /* Address, is an unsigned integer */
The output displayed may be 17502 (address of n is machine dependent). The
pointer p is originally assigned the value 17500. The incrementing of p using p++
increments the number of bytes of the storage class for the particular machine. If the
system used four bytes to store an integer, then p++ would have resulted in p being equal
to 17504.
However it is also possible for a pointer to perform certain operations on the
data that it is pointing to. To perform such an operation we will have to use the *
symbol before the pointer variable in the program.
The code below shows what would happen when we perform an increment
operation with a pointer on the data that is being pointed.
Example 3 : The following code illustrate the use of pointers in arithmetic
operation.
int n, *p;
n = 9;
p = &n;
(*) p++;
p \
In the above example the value of the data that is being pointed is
manipulated using the pointer variable. The value of the variable n is changed to 10
after the program is executed.
NOTE
Example 4 : If ptr1 and ptr2 are two pointer variables pointing to the variables
a and b then the following are valid use of pointers in arithmetic operations.
1. *ptr1 = *ptr1 + *ptr2; same as a+b
2. sum = *ptr1 + 10; same as a + 10
3. sum += *ptr2; same as sum + b
4. result= 10 * - *ptr1 / *ptr2; same as ((10 * (-(a)))/(b)
5. ptr1 > ptr2
6. ptr2 != ptr2
NOTE
Example 5 : If ptr1 and ptr2 are declared as pointer variables, then the following are invalid
use of pointers in arithmetic operations. We cannot use pointers in addition,
multiplication and division of addresses.
Example for illegal use of pointers:
Program 5 : To illustrate the pointer expression and pointer arithmetic.
#include<stdio.h>
main()
{
int a,b,x,y,z;
int *ptr1,*ptr2;
a = 30;
b = 6;
ptr1=&a; /* Address of a is assigned to pointer variable ptr1 */
ptr2=&b; /* Address of b is assigned to pointer variable ptr2*/
x = *ptr1 + *ptr2 - 6;
y = 6 - *ptr1 / *ptr2 + 30;
\nAddressof
\nAddressof
\na =%d,
\nx=%d, y=
*ptr1=*ptr1+70; /* Content of a=a+ 70 */
*ptr2=*ptr2*2; /* Content of b=b* 2 */
\
}
OUTPUT
Example 6: Pointers can be compared using relational operators. Expressions such as
ptr1 > ptr2, ptr1=ptr2 and ptr1!=ptr2 are allowed. Such comparisons are useful when
both pointer variables point to elements of the same array.
SPACE REQUIRED FOR POINTER VARIABLES
The amount of memory space allotted when a variable is created and
compiled depends on the data type of the variable. The amount of space reserved for
a variable has already been explained in the previous section. In this section, we try
to understand how much space will be allotted to a pointer variable of different types
of data. The program below highlights this point clearly.
Program6: To show the amount of space required to store variables and space
reserved for pointers.
#include<stdio.h>
main()
{
int a=5,*int_ptr;
char
float c=17.53,*float_ptr;
int_ptr=&a;
float_ptr=&b;
char_ptr=&c;
Value of integer=%d \
Value of char=%c \ b);
printf( Value of float=%f \
of space for int ptr=%ubytes\
ofspaceforcharptr=%ubytes \
\
}
OUTPUT
What is observed from the above is a very important fact. The amount of space
to store different variables may vary. However the size of all the addresses available is
the same and depends on the word length of the computer being used. Thus we observe
that all the outputs are the same i.e., a pointer is created to hold the address of another
memory location and the size of the address is the same immaterial of the type of data
it holds, thus the outputs are the same.
POINTERS AND FUNCTIONS
Pointers are used very much with functions. Also sometimes complex
function can easily be represented and accessed only with a pointer. Arguments can
be passed to one of the following methods.
1. Passing values of the arguments (Call by Value)
2. Passing the addresses of the arguments (Call by Reference)
Call by value
We have seen that when a function is invoked, a correspondence is
established between the formal and actual parameters. A temporary storage is created
where the value of the actual parameter is stored. The formal parameter picks up its
value from this storage area. This mechanism of data transfer, between the actual and
formal parameters, allows the actual parameters to be an expression, arrays, etc.
Such parameter is called value parameters and mechanism of data transfer is
referred to as Call-By-Value. The corresponding formal parameter represents a local
variable in the called function. The current value of the corresponding actual
parameter becomes the initial value of the formal parameter. The value of formal
parameter may then change in the body of the subprogram by assignment or input
statements. This will not change the value of the actual parameter.
Definition
Program 7:A Cprogramto illustrate thefunction usingcallby valuemechanism.
#include<stdio.h> void
function(int,int);
main()
{
int a,b;
a=20;
b=30;
b=%d beforefunctioncall \
function(a,b);
afterfunctioncall \
}
/* Callbyvaluefunction */
Void function(int x,int y)
{
x = x + x;
y = y + y;
}
OUTPUT
Call by reference
Whenever a function call is made if we pass the address of a variable to a
function, the parameters receiving the address should be pointers. The process of
calling a function using pointers to pass the address of variable is known as Call-By-
Reference. Th
variable used in the call i.e., any changes made to the copied variables will affect the
original variables also.
Definition
Program 8 : A C program to illustrate the function using call by reference
mechanism.
#include<stdio.h>
main()
{
int a,b;
void function(int*,int*);
a=20;
b=30;
\
function(&a,&b);
\
}
/* Callbyreferencefunction */
Void function(int*x,int*y)
{
*x = *x + *x;
*y = *y + *y;
}
When the function is called, the address of the variable a, not its value, is
passed into the function. In the function the receiving variables are declared as a
pointer thus the address of the variable is passed. Since x represents the address of
a, the value of a is changed from 20 to 40. Therefore, the output of the above program
segment will be as shown above.
Program 9: A C program to exchange the contents of the two variables using call
by value and call by reference.
#include<stdio.h>
main()
{
int a,b;
voidswap_val(int,int); /* Function prototype */
voidswap_ref(int*,int*);
\
\
swap_val(a,b);
\
swap_ref(&a,&b);
\
}
/* Function to exchange two values using call by value */
Void swap_val(intx,inty)
{
int temp;
temp = x;
x = y;
y = temp;
}
/* Function to exchange two values using call by reference */
Void swap_ref(int*x,int*y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
OUTPUT
Using the technique of call by reference in an intelligent manner it is possible for
us to make a function return more than one value at any instant of time, whereas till
now our function could return only one value.
Program 10 : A C program to make a function returning more than one value.
#include<stdio.h>
#define PI 3.1415
void calculate(int,float*,float*);;
main()
{
int r;
float a,c;
\
calculate(r,&a,&c);
=%d\
=%f \
\
}
/* Functiontocalculatetheareaandcircumferenceofacircle */
Void calculate(intx,float*y,float*z)
{
*y = PI* x* x;
*z = 2 * PI * x;
}
OUTPUT
POINTER AND ARRAYS
An array is a name given to a set of memory locations of the same type of data.
It is a very popular data type especially when we are working with large amounts of
data. However discussing arrays and not discussing pointers and vice versa is not
possible at all. In actuality all arrays make use of pointers internally.
Before we start studying pointers, let us note a few points about pointers:
1. An array is a collection of memory locations called by the same name and
holding the same type of data and accessed with the help of a
subscript.
2. Before using an array it must be declared.
Example : char name[20];
3. The accessing of elements at any location is done with the help of the
name of the array. The name of the array always represents the address of
the first location of the array. Thus data at any location is accessed with
the help of the expression.
LOC( i ) = Address of first location + Subscript value * size of data type
One-dimensional array
Consider the following declaration
int a[ ], *ptr;
The pointer could be assigned the address of a[0]
ptr = &a[0];
but this syntax would not be in the accepted style. You could simply assign the
pointer the value of a.
ptr = a;
The address of the first element is assigned to a pointer variable ptr. If the
pointer is incremented to the next data element, then the following expression of the
equality operator is same.
ptr++
ptr + 6
*(ptr + 6)
Program11:To display the contents of an array using name and also a pointer.
#include<stdio.h>
main()
{
int a[100];
int i,n;
int *ptr;
\
\
for(i=0;i<n;i++)
ptr = a;
\nArrayelementsare\
for(i=0;i<n; i++)
{
a[%d]=%d\ i));
}
}
OUTPUT
a[0] = 34
a[2] = 67
a[3] = 54
a[4] = 22
POINTERS AND STRINGS
Similar to the way where a large amount of data is stored in an integer array,
a group of characters should be stored in a character array. Character arrays are also
known as strings. A string constant is a one-dimensional character array where the
last element is terminated by \ Arrays and pointers to character arrays can be used
to perform a number of string functions. For example a program to find string length
and string copy is implemented later.
Program12: A C program to find the length of a string using pointer variable.
#include<stdio.h>
main()
{
char str[10]; /*Characterarray */
char *sptr; /*sptrisapointerofcharacter */
int length;
sptr = str; /*assignstheaddressoffirstcharacterofstr */
\
\0')
{
sptr++;
}
length = sptr-str;
\nLengthofthestring
}
OUTPUT
ARRAYS OF POINTERS
As we can have arrays of integers or an array of floats, similarly there can be an
array of pointers. Since a pointer variable always contains an address, an array of
pointer would be nothing but a collection of address. The address present in the array
of pointers can be or can be addresses of isolated variables or addresses of array
elements or any other address. All rules that apply to an ordinary array apply to the
array of pointers as well.
Program 13 : A C program to illustrate an array of pointers.
#include<stdio.h>
main()
{
int *arrptr[5]; /*arrayofintegerpointers*/
int i=80,j=34,k=97;
int l=76,m=56,n;
arrptr[0] = &i;
arrptr[1] = &j;
arrptr[2] = &k;
arrptr[3] = &l;
arrptr[4] = &m;
for(n=0;n<=4;n++)
\
}
OUTPUT
Malloc and Calloc:
Since C is a structured language, it has some fixed rules for programming. One of
them includes changing the size of an array. An array is a collection of items stored
at contiguous memory locations.
What if there is a requirement to change this length (size). For Example,
If there is a situation where only 5 elements are needed to be entered in this
array. In this case, the remaining 4 indices are just wasting memory in this
array. So there is a requirement to lessen the length (size) of the array from 9
to 5.
Take another situation. In this, there is an array of 9 elements with all 9 indices
filled. But there is a need to enter 3 more elements in this array. In this case, 3
indices more are required. So the length (size) of the array needs to be changed
from 9 to 12.
This procedure is referred to as Dynamic Memory Allocation in C.
Therefore, C Dynamic Memory Allocation can be defined as a procedure in which the
size of a data structure (like Array) is changed during the runtime.
C provides some functions to achieve these tasks. There are 4 library functions
provided by C defined under <stdlib.h> header file to facilitate dynamic memory
allocation in C programming. They are:
malloc()
calloc()
free()
realloc()
malloc() method
single large block of memory with the specified size. It returns a pointer of type void
n
time so that it has initialized each block with the default garbage value initially.
Syntax:
ptr = (cast-type*) malloc(byte-size)
For Example:
ptr = (int*) malloc(100 * sizeof(int));
Since the size of int is 4 bytes, this statement will allocate 400 bytes of memory. And,
the pointer ptr holds the address of the first byte in the allocated memory.
If space is insufficient, allocation fails and returns a NULL pointer.
calloc() method:
specified number of blocks of memory of the specified type. it is very much similar to
malloc() but has two different points and these are:
It has two parameters or arguments as compare to malloc().
Syntax:
ptr = (cast-type*)calloc(n, element-size);
here, n is the no. of elements and element-size is the size of each element.
For Example:
ptr = (float*) calloc(25, sizeof(float));
This statement allocates contiguous space in memory for 25 elements each with the
size of the float. If space is insufficient, allocation fails and returns a NULL pointer.