VELAMMAL ENGINEERING COLLEGE
An Autonomous Institution, Affiliated to Anna University Chennai, & Approved by AICTE Delhi
UNIT IV
POINTERS
1
Velammal Engineering college/Dept. of CSE
UNIT-IV POINTERS
• Pointer Fundamentals – Pointer
Declaration – Passing Pointers to a
Function – Pointers and one dimensional
arrays – operations on pointers–
Dynamic memory allocation.
Address in C
• scanf("%d", &var);
&var will give you its address in the memory.
• Example program:
INTRODUCTION
• A pointer provides a way of accessing a
variable without referring to the variable
directly.
• The mechanism used for this is the address of
the variable.
• A program statement can refer to a variable
indirectly using the address of the variable.
Pointer Fundamentals
• C uses pointers in three main ways.
1. Pointers in C provide an alternative means of accessing information
stored in arrays, which is especially valuable when working with
strings. There is an intimate link between arrays and pointers in C.
2. C uses pointers to handle variable parameters passed
to functions.
3. They are used to create dynamic data structures, those that are built
up from blocks of memory allocated from the heap at run-time. This
is only visible through the use of pointers.
Pointer Fundamentals (cntd)
• ADDRESS OPERATOR (&)
int i = 3;
• This declaration tells the C compiler to
– Reserve space in memory to hold the
integer value
– Associate the name i with this memory
location
– Store the value 3 at this location
Pointer Definition
• A pointer variable is a variable that holds the memory
address of another variable
• Put another way, the pointer does not hold a value;
instead, it holds the address of another variable
• They ‘point’ to a particular point in memory
Question
• What is mean by pointer?
• How to declare a pointer variable?
Declaring a Pointer
• A pointer variable is declared by preceding its name with an asterisk(*).
• The syntax for declaring a pointer variable is
datatype *pointer_variable;
• datatype is the type of data that the pointer is allowed to hold the address of
• pointer_variable is the pointer variable name that is used to refer to the address
of a variable of type datatype.
Example for pointer declaration
• An example of a pointer declaration would be
char *ptr;
• The above declaration should be evaluated as:
– ptr is a pointer to char type data.
– char is not the data type of ptr.
– ptr is an identifier of type pointer and
– char is a data specifier that is used to indicate what type of data
is at the memory address that ptr is holding.
Example for pointer declaration (cntd)
• Consider the following declaration.
int *a;
• The above declaration indicates that a is a pointer type variable that points to int
type data. That is, the int indicates that the pointer variable is intended to store the
address of an integer variable. Such a pointer is said to ‘point to’ an integer.
float *t;
• The above declaration represents the fact that t is a pointer type variable that
points to float type data
Example for pointer declaration
(cntd)
• Some declarations are listed
Example Program
Initializing Pointers
• Unlike a simple variable that stores a value, a
pointer must be initialized with a specified
address prior to its use.
• The syntax for initializing a pointer variable is
datatype *pointer_variable = &variable_name ;
Example Program
• The following program shows how to use the address operator to assign the address of a variable to a pointer.
• This program also demonstrates that the value of a pointer is the same as the address to which the pointer points.
#include <stdio.h>
int main()
{
int i = 5;
int *ptr = &i;
printf(“nThe address of i using &num is %p”, &i);
printf(“nThe address of i using Ptr is %p”, ptr);
return 0;
}
Example Program
Any number of pointers can point to the same address. For
example, we could declare p, q, and r as integer pointers and
set all of them to point to i as shown here.
int i=3;
int *p, *q, *r;
p = &i;
q = &i;
r = p;
Printing pointer value
A pointer variable contains a memory address that points to another variable. To print the memory address stored in pointers
and non-pointer variables using the %p conversion specifier is used
#include <stdio.h> Output: p = 0022FF2C
int main(void)
{
int a=10, *p;
p=&a;
printf(“n p = %p”, p);
return 0;
}
Indirection Operator and Dereferencing
• The primary use of a pointer is to access and, if appropriate, change the
value of the variable that the pointer is pointing to
• The other pointer operator available in C is ‘*’, called the ‘value at
address’ operator.
• It returns the value stored at a particular address
• The value at address operator is also called indirection operator or
dereference operator
Indirection Operator and Dereferencing (cntd)
In the following program, the value of the integer variable num is changed twice.
#include <stdio.h>
int main()
{
int num = 5;
int *iPtr = &num;
printf(“n The value of num is %d”, num);
num = 10;
printf(“n The value of num after num = 10 is: %d”, num);
*iPtr = 15;
printf(“n The value of num after *iPtr = 15 is: %d”, num);
return 0;
}
Indirection Operator and Dereferencing (cntd)
• The second change should be familiar, by the direct assignment of a value to num, such as num=10
• However, the third change is accomplished in a new way, by using the indirection operator
• *iPtr = 15;
• The indirection operator is an asterisk, the same asterisk that is used to declare the pointer or to perform
multiplication
• However, in this statement the asterisk is not being used in a declaration or to perform multiplication
Addition Using Pointers
#include <stdio.h>
int main()
{
int a,b,c;
int *pa,*pb,*pc;
pa=&a;
pb=&b;
pc=&c;
printf(“n ENTER THE FIRST NUMBER:”);
scanf(“%d”,pa);
printf(“n ENTER THE SECOND NUMBER:”);
scanf(“%d”,pb);
*pc=*pa+*pb;
printf(“n SUM IS %d”,*pc);
return 0;
}
VOID POINTER
• A void pointer is a special type of pointer
• It can point to any data type, from an integer value or a float to
a string of characters
• The limitation is that the pointed data cannot be referenced
directly
• type casting or assignment must be used to turn the void
pointer to a pointer of a concrete data type to which we can
refer.
VOID POINTER
Example:
#include <stdio.h>
int main()
{
int a=5,
double b=3.1415;
void *vp;
vp=&a;
printf(“n a= %d”, *((int *)vp));
vp=&b;
printf(“n a= %d”, *((double *)vp));
return 0;
}
NULL POINTER
• A null pointer is a special pointer that points nowhere
• That is, no other valid pointer to any other variable or array cell
or anything else will ever be equal to a null pointer
• The null pointer in the program is assigning with a keyword
NULL, which is defined by several standard header files,
including <stdio.h>, <stdlib.h>, and <string.h>
NULL POINTER (cntd)
#include <stdio.h>
int main()
{
int *p;
p = NULL;
printf(“n The value of p is %u”, p);
return 0;
}
USE OF POINTERS
Call by address
USE OF POINTERS (cntd)
Call by Reference
Passing pointers to functions
C programming allows passing a pointer to a
function. To do so, simply declare the function
parameter as a pointer type
Passing pointers to functions (cntd)
#include <stdio.h>
void salaryhike(int *var, int b)
{
*var = *var+b;
}
int main()
{
int salary=0, bonus=0;
printf("Enter the employee current salary:");
scanf("%d", &salary);
printf("Enter bonus:");
scanf("%d", &bonus);
salaryhike(&salary, bonus);
printf("Final salary: %d", salary);
return 0;
}
Enter the employee current salary:10000
Enter bonus:2000
Pointers and one dimensional arrays
• Pointers and arrays are inseparably related, but they
are not synonymous.
• An array is a non-empty set of sequentially indexed
elements having the same type of data. Each
element of an array has a unique identifying index
number.
• The array a is laid out in memory as a contiguous
block, as shown.
int a[]={10, 20, 30, 40, 50};
• Array notation is a form of pointer notation.
• The name of an array is the beginning address of the array, called the base address
of the array.
• The array name is referred to as an address constant.
• Both array and &array would give the base address of the array, but the only
difference is under ANSI/ISO Standard C, &array yields a pointer, of type pointer to-
array of-the data type to the entire array.
#include <stdio.h>
int main()
{
int a[]={10, 20, 30, 40, 50};
printf(“%u %u”, a, &a[0]);
return 0;
}
Output:
2147478270 2147478270
• With the name of the array actually being a constant that
represents a memory address, the name of the array can be
used as a pointer and an integer value can be used to
represent an offset from the base address.
• An element of the array a is addressed as a[i] and the address
of the ith element of the array a is given by &a[i]=a + i size of
the type pointed to by a.
• The expression a + i (with integer i) means the address of the
ith element beyond the one a points to. This is known as
scaling.
• As indirection operator ‘*’ implies value at address, a[i] is
equivalent to *(a+i).
Example
#include <stdio.h>
int main()
{
int a[]={10, 20, 30, 40, 50};
int i;
for(i=0;i<5;i++)
{
printf("n %d", a[i]);
printf("n %d",*(a+i));
printf("n %d", &a[i]);
}
return 0;
}
Output:
10
10
1011568592
20
20
1011568596
30
30
1011568600
40
40
1011568604
50
50
1011568608
• All the following four expressions are the same when their addresses are considered.
a[i], *(a + i), *(i + a), i[a]
• In the expression a[i], i must be an integer. The other may either be an array name or a
pointer.
• For any one-dimensional array a and integer i, the following relationships are always true.
1. &a[0] == a
2. &a[i] == a + i
3. a[i] == *(a + i)
4. (&a[i] - &a[j]) == (i - j)
• A pointer variable (of
the appropriate type)
can also be used to
initialize or point to the
first element of the
array. Then it can also
be used as above.
• Pointers and arrays are so closely related that their
notation can be interchanged such that the following
terms are identical if p contains the value of a.
• a[i]
• *(a + i)
• *(p + i)
• p[i]
where i=0,1,2,...(N–1). N is the size of the array.
This equivalence does not mean that arrays and pointers are the same (they are, in fact, quite
different) but that they can be used in related ways, and that certain operations may be used
between them. These operations are as follows.
• The first such operation is that it is possible to (apparently) assign an array to a pointer.
int a[10];
int *p;
p = a;
C defines the result of this assignment to be that p receives a pointer to the first element of a. In
otherwords,
p = &a[0];
• The second aspect of the equivalence is that the array subscripting notation [i] can be
applied on pointers,too. p[3] can be written as *(p + 3).
The pointer to an array does not always point to the first element of the array. It can point to any
element of the array. For example,
int a[]={10,20,30,40,50};
int *p;
p = a + 3;
can also be written as follows
p = &a[0] + 3;
which, in turn, gives the same result as
p = &a[3];
Operations on Pointers
• If p is declared as a pointer variable of any
type and it has been initialized properly,
then, just like a simple variable,any
operation can be performed with *p.
• Because *implies value at address, working
with *p means working with the variable
whose address is currently held by p.
The only valid operations on pointers are as follows.
• Assignment of pointers to the same type of pointers.
• Adding or subtracting a pointer and an integer.
• Subtracting or comparing two pointers.
• Incrementing or decrementing the pointers.
• Assigning the value 0 to the pointer variable and comparing 0 with the pointer.
Assignment
Pointers with the assignment operators can be used if
thefollowing conditions are met.
• The left-hand operand is a pointer and the right-hand
operand is a null pointer constant.
• One operand is a pointer to an object of incompatible
type and the other is a pointer to void.
• Both the operands are pointers to compatible types.
#include <stdio.h>
int main()
{
int i=5;
int *ip;
void *vp;
ip = &i;
vp = ip;
//printf(“n *vp= %d”,*vp); —————— ERROR
ip = vp;
printf(“n *ip= %d”,*ip);
return 0;
}
This program gives an error in the first printf statement stating ‘not an allowed type’ because no type is associated with a
void pointer.
• The right version of this program is as follows.
#include <stdio.h>
int main()
{
int i=5;
int *ip;
void *vp;
ip = &i;
vp = ip;
printf(“n *vp= %d”,*((int *)vp));
ip = vp;
printf(“n *ip= %d”,*ip);
return 0;
}
Output:
*vp=5
*ip=5
Addition or Subtraction with Integers
• a ‘+’ between a pointer and an integer does the
same offset computation as explained earlier, but
leaves the result as a pointer.
• We can add a value to the pointer variable. The
formula of adding value to pointer is given below:
new_address= current_address + (number * size_of(da
ta type))
#include<stdio.h>
int main(){
int number=50;
int *p;//pointer to int
p=&number; //stores the address of number variable
printf("Address of p variable is %u n",p);
p=p+3; //adding 3 to pointer variable
printf("After adding 3: Address of p variable is %u n",p); return 0;
}
Output:
Address of p variable is 3214864300
After adding 3:
Address of p variable is 3214864312
• As you can see, the address of p is 3214864300.
But after adding 3 with p variable, it is
3214864312, i.e., 4*3=12 increment. Since we are
using 64-bit architecture, it increments 12.
Consider the following two
versions of same program.
(a)
#include <stdio.h>
int main(void)
{
int a[] = {10, 12, 6, 7, 2};
int i;
int sum = 0;
for(i=0; i<5; i++)
{
sum += a[i];
}
printf(“%dn”, sum);
return 0;
}
(b)
#include <stdio.h>
int main(void)
{
int a[] = {10, 12, 6, 7, 2};
int i;
int sum = 0;
for(i=0; i<5; i++)
{
sum += *(a + i);
}
printf(“%dn”, sum);
return 0;
}
• Therefore, expressions can add (or subtract, which is
equivalent to adding negative values) integral values
to the value of a pointer to any object type. The
result has the type of the pointer and if n is added,
then the result points n array elements away from
the pointer.
This is a typical string-processing function.
• Pointer arithmetic and
dereferencing are used
to search for various
characters or patterns
Using p++
is a pointer to an
ment in an array, then
1) points to the next
ment in the array.
e statement p++ can be
d to step a pointer
er the elements in an
ay.
#include <stdio.h>
int main(void)
{
int a[] = {10, 12, 6, 7, 2};
int i;
int sum = 0;
int *p;
p = a;
for(i=0; i<5; i++)
{
sum += *p;
p++;
}
printf(“%dn”, sum);
return 0;
}
It is possible to traverse an array starting from a pointer to any element in the array. Consider
the following program.
/* initialize ptr to point to element arr[3] */
ptr = &arr[3];
*ptr = 1.0; /* arr[3] = 1.0 */
*(ptr - 1) = 0.9; /* arr[2] = .9 */
*(ptr + 1) = 1.1; /* arr[4] = 1.1 */
/* initialize iptr in the same way */
iptr = &a[3];
*iptr = 0;
*(iptr - 1) = -1;
*(iptr + 1) = 2;
for(i = 0; i < N; i++)
{
printf(“arr[%d] = %f”, i, *(arr + 1));
printf(“a[%d] = %dn”, i, a[i]);
return 0;
}
}
#include <stdio.h>
#defi ne N 5
int main()
{
float arr[N], *ptr;
int *iptr, a[N], i;
/* initialize */
for(i = 0; i < N; i++)
{
arr[i] = 0.3;
a[i] = 1;
}
• arr[0] = 0.300000 a[0] = 1
• arr[1] = 0.300000 a[1] = 1
• arr[2] = 0.900000 a[2] = -1
• arr[3] = 1.000000 a[3] = 0
• arr[4] = 1.100000 a[4] = 2
C Pointer Subtraction
• Like pointer addition, we can subtract a value from
the pointer variable. Subtracting any number from a
pointer will give an address. The formula of
subtracting value from the pointer variable is given
below:
new_address= current_address (number * size_of(dat
a type))
#include<stdio.h>
int main(){
int number=50;
int *p;//pointer to int
p=&number;//stores the address of number variable
printf("Address of p variable is %u n",p);
p=p-3; //subtracting 3 from pointer variable
printf("After subtracting 3: Address of p variable is %u n",p);
return 0;
}
Output:
Address of p variable is
3214864300
After subtracting 3:
Address of p variable is
3214864288
Increment operator
Increment operator
#include <stdio.h>
int main()
{
int A[] = {10, 20, 30, 40, 50};
int *p, i;
p = A;
printf(“*p : %inn”, *p);
i = *(p++);
printf(“i is: %in”, i);
printf(“*p is: %inn”, *p);
i = (*p)++;
printf(“i is: %in”, i);
printf(“*p is: %inn”, *p);
i = *(++p);
printf(“i is: %in”, i);
printf(“*p is: %inn”, *p);
i = ++(*p);
printf(“i is: %in”, i);
printf(“*p is: %inn”, *p);
return 0;
}
Output:
*p : 10
i is : 10
*p is: 20
i is: 20
*p is: 21
i is: 30
*p is: 30
i is: 31
*p is: 31
Decrement operator
#include <stdio.h>
int main(void)
{
int a[] = {10, 20, 30, 40, 50};
int i, *p;
p=a+4;
for(i=4; i>=0; i––)
printf(“%dn”, *(p-i));
return 0;
}
Output:
10
20
30
40
50
Subtraction of Pointers
• For example, one might
write
p2 = p1 + 3;
Applying a little algebra,
p2 - p1 = 3
Here both p1 and p2 are pointers pointing to the elements of the same
array. From this it can be concluded that the two pointers are subtracted,
as long as they point into the same array.
#include <stdio.h>
int main()
{
double a[2],*p,*q;
p=a;
q=p+1;
printf(“%dn”,q – p);
return 0;
}
Output:
1
Given two pointers p and q of the same type, the difference p – q is
an integer k such that adding k to q yields p.
Subtraction of Pointers
• To print the number of
bytes resulting from q-
p, each pointer may be
typecast.
#include <stdio.h>
int main()
{
double a[2],*p,*q;
p=a;
q=p+1;
printf(“%dn”,(int)q-(int)p);
return 0;
}
Output:
8
Comparing Pointers
• C allows pointers to be
compared with each other. If
two pointers compare equal
to each other, then they
point to the same thing,
whether it is an object or the
non-existent element of the
end of an array
• If two pointers point to the same thing, then they
compare equal to each other.
• The relational operators >, <=, and so on give the result
that would be expected if the pointers point to the same
array: if one pointer compares less than another, then it
points nearer to the front of the array.
#include <stdio.h>
int main(void)
{
int a[] = {10, 20, 30, 40, 50};
int i, *p;
for(p=a; p<=a+4; p++)
printf(“%dn”, *p);
return 0;
}
Output:
10
20
30
40
50
The following program will print the line in reverse order..
#include <stdio.h>
#include <string.h>
int main()
{
char a[50];
void reverse(char *);
printf(“n Enter the string:”);
gets(a);
reverse(a);
printf(“nAfter reversing the string is :n”);
puts(a);
return 0;
}
void reverse(char *string)
{
char *lp = string; /* left pointer */
char *rp = &string[strlen(string)-1];
/* right pointer */
char tmp;
while(lp < rp)
{
tmp = *lp;
*lp = *rp;
*rp = tmp;
lp++;
rp––;
}
}
Output:
Enter the string:manas
After reversing the string is:
sanam
Pointer arithmetic summary
DYNAMIC MEMORY ALLOCATION
• An array is a collection of a fixed number of
values. Once the size of an array is declared, you
cannot change it.
• Sometimes the size of the array you declared
may be insufficient.
• To solve this issue, you can allocate memory
manually during run-time.
• This is known as dynamic memory allocation in C
programming.
To allocate memory dynamically, library functions
are malloc(), calloc(), realloc() and free() are used.
These functions are defined in
the <stdlib.h> header file.
malloc() allocates single block of requested memory.
calloc() allocates multiple block of requested memory.
realloc() reallocates the memory occupied by malloc() or calloc() functions.
free() frees the dynamically allocated memory.
DYNAMIC MEMORY ALLOCATION
static memory allocation dynamic memory allocation
memory is allocated at compile time. memory is allocated at run time.
memory can't be increased while
executing program.
memory can be increased while
executing program.
C malloc()
• The name "malloc" stands for memory
allocation.
• The malloc() function reserves a block of
memory of the specified number of bytes.
• And, it returns a pointer of void which can be
casted into pointers of any form.
• Syntax of malloc()
ptr = (castType*) malloc(size);
ptr = (float*) malloc(100 * sizeof(float));
The above statement allocates 400 bytes of memory. It's
because the size of float is 4 bytes. And, the pointer ptr holds
the address of the first byte in the allocated memory.
C calloc()
• The name "calloc" stands for contiguous
allocation.
• The malloc() function allocates memory
and leaves the memory uninitialized.
• Whereas, the calloc() function allocates
memory and initializes all bits to zero.
• Syntax of calloc()
ptr = (castType*)calloc(n, size);
ptr = (float*) calloc(25, sizeof(float));
The above statement allocates contiguous
space in memory for 25 elements of type
float.
C free()
• Dynamically allocated
memory created with
either calloc() or
malloc() doesn't get
freed on their own. You
must explicitly use
free() to release the
space.
• Syntax of free()
free(ptr);
This statement frees the
space allocated in the
memory pointed by ptr.
C realloc()
• If the dynamically
allocated memory is
insufficient or more
than required, you can
change the size of
previously allocated
memory using the
realloc() function.
• Syntax of realloc()
ptr = realloc(ptr, x);
Here, ptr is reallocated
with a new size x.
Example 1: malloc() and free()
Program to calculate the sum of n numbers entered by the user
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, i, *ptr, sum = 0;
printf("Enter number of elements: ");
scanf("%d", &n);
ptr = (int*) malloc(n * sizeof(int));
// if memory cannot be allocated
if(ptr == NULL)
{
printf("Error! memory not allocated.");
exit(0);
}
printf("Enter elements: ");
for(i = 0; i < n; ++i)
{
scanf("%d", ptr + i);
sum += *(ptr + i);
}
printf("Sum = %d", sum);
// deallocating the memory
free(ptr);
return 0;
}
Example 2: calloc() and free()
// Program to calculatethe sum of n numbers entered by the user
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, i, *ptr, sum = 0;
printf("Enternumber of elements: ");
scanf("%d", &n);
ptr = (int*) calloc(n, sizeof(int));
if(ptr== NULL)
{
printf("Error!memory not allocated.");
exit(0);
}
printf("Enter elements: ");
for(i = 0; i < n; ++i)
{
scanf("%d", ptr + i);
sum += *(ptr + i);
}
printf("Sum = %d", sum);
free(ptr);
return 0;
}
Example 3: realloc()
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *ptr, i , n1, n2;
printf("Enter size: ");
scanf("%d", &n1);
ptr = (int*) malloc(n1 * sizeof(int));
printf("Addresses of previously allocated memory: ");
for(i = 0; i < n1; ++i)
printf("%un",ptr + i);
printf("nEnter the new size: ");
scanf("%d", &n2);
// rellocatingthe memory
ptr = realloc(ptr, n2 * sizeof(int));
printf("Addresses of newly allocatedmemory: ");
for(i = 0; i < n2; ++i)
printf("%un",ptr + i);
free(ptr);
return 0;
}
Output:
Enter size: 2
Addresses of previously allocated memory:26855472
26855476
Enter the new size: 4
Addresses of newly allocated memory:26855472
26855476
26855480
26855484
The four functions of interest are as follows:
• void* malloc(size_t size): Request a contiguous
block of memory of the given size in the heap. malloc() returns a pointer to the heap block or NULL if the request is not
satisfied.
• calloc(): works like malloc, but initializes the memory to zero if possible. The prototype is
void * calloc(size_t count, size_t eltsize)
This function allocates a block long enough to contain
an array of count elements, each of size eltsize. Its
contents are cleared to zero before calloc returns.
• void free(void* block): free() takes a pointer to a
heap block earlier allocated by malloc() and returns
that block to the heap for reuse.
• void* realloc(void* block, size_t size): Take an
existing heap block and try to reallocate it to a
heap block of the given size which may be larger or
smaller than the original size of the block
Example for Malloc()
#include <stdlib.h>
#include <stdio.h>
int main()
{
int * ip;
double * dp;
fl oat * fp1;
fl oat * fp2;
ip = (int *) malloc(sizeof(int));
if(ip == NULL)
{
printf(“out of memoryn”);
exit(-1);
}
dp =(double *) malloc(sizeof(double));
if(dp == NULL)
{
printf(“out of memoryn”);
exit(-1);
}
fp1 =(fl oat *) malloc(sizeof(fl oat));
if(fp1 == NULL)
{
printf(“out of memoryn”);
exit(-1);
}
fp2 = (fl oat *) malloc(sizeof(fl oat));
if(fp2 == NULL)
{
printf(“out of memoryn”);
exit(-1);
}
*ip = 42;
*dp = 3.1415926;
*fp1 = -1.2;
*fp2 = 0.34;
printf(“ip: address %d; contents %dn”, (int)ip, *ip);
printf(“dp: address %d; contents %fn”, (int)dp, *dp);
printf(“fp1: address %d; contents %fn”, (int)
fp1, *fp1);
printf(“fp2: address %d; contents %fn”, (int
fp2, *fp2);
return 0;
}
Output:
• ip: address 133792;
contents 42
• dp: address 133808;
contents 3.141593
• fp1: address 133824;
contents -1.200000
• fp2: address 133840;
contents 0.340000

4 Pointers.pptx

  • 1.
    VELAMMAL ENGINEERING COLLEGE AnAutonomous Institution, Affiliated to Anna University Chennai, & Approved by AICTE Delhi UNIT IV POINTERS 1 Velammal Engineering college/Dept. of CSE
  • 2.
    UNIT-IV POINTERS • PointerFundamentals – Pointer Declaration – Passing Pointers to a Function – Pointers and one dimensional arrays – operations on pointers– Dynamic memory allocation.
  • 3.
    Address in C •scanf("%d", &var); &var will give you its address in the memory. • Example program:
  • 4.
    INTRODUCTION • A pointerprovides a way of accessing a variable without referring to the variable directly. • The mechanism used for this is the address of the variable. • A program statement can refer to a variable indirectly using the address of the variable.
  • 5.
    Pointer Fundamentals • Cuses pointers in three main ways. 1. Pointers in C provide an alternative means of accessing information stored in arrays, which is especially valuable when working with strings. There is an intimate link between arrays and pointers in C. 2. C uses pointers to handle variable parameters passed to functions. 3. They are used to create dynamic data structures, those that are built up from blocks of memory allocated from the heap at run-time. This is only visible through the use of pointers.
  • 6.
    Pointer Fundamentals (cntd) •ADDRESS OPERATOR (&) int i = 3; • This declaration tells the C compiler to – Reserve space in memory to hold the integer value – Associate the name i with this memory location – Store the value 3 at this location
  • 7.
    Pointer Definition • Apointer variable is a variable that holds the memory address of another variable • Put another way, the pointer does not hold a value; instead, it holds the address of another variable • They ‘point’ to a particular point in memory
  • 8.
    Question • What ismean by pointer? • How to declare a pointer variable?
  • 9.
    Declaring a Pointer •A pointer variable is declared by preceding its name with an asterisk(*). • The syntax for declaring a pointer variable is datatype *pointer_variable; • datatype is the type of data that the pointer is allowed to hold the address of • pointer_variable is the pointer variable name that is used to refer to the address of a variable of type datatype.
  • 10.
    Example for pointerdeclaration • An example of a pointer declaration would be char *ptr; • The above declaration should be evaluated as: – ptr is a pointer to char type data. – char is not the data type of ptr. – ptr is an identifier of type pointer and – char is a data specifier that is used to indicate what type of data is at the memory address that ptr is holding.
  • 11.
    Example for pointerdeclaration (cntd) • Consider the following declaration. int *a; • The above declaration indicates that a is a pointer type variable that points to int type data. That is, the int indicates that the pointer variable is intended to store the address of an integer variable. Such a pointer is said to ‘point to’ an integer. float *t; • The above declaration represents the fact that t is a pointer type variable that points to float type data
  • 12.
    Example for pointerdeclaration (cntd) • Some declarations are listed
  • 13.
  • 14.
    Initializing Pointers • Unlikea simple variable that stores a value, a pointer must be initialized with a specified address prior to its use. • The syntax for initializing a pointer variable is datatype *pointer_variable = &variable_name ;
  • 15.
    Example Program • Thefollowing program shows how to use the address operator to assign the address of a variable to a pointer. • This program also demonstrates that the value of a pointer is the same as the address to which the pointer points. #include <stdio.h> int main() { int i = 5; int *ptr = &i; printf(“nThe address of i using &num is %p”, &i); printf(“nThe address of i using Ptr is %p”, ptr); return 0; }
  • 16.
    Example Program Any numberof pointers can point to the same address. For example, we could declare p, q, and r as integer pointers and set all of them to point to i as shown here. int i=3; int *p, *q, *r; p = &i; q = &i; r = p;
  • 17.
    Printing pointer value Apointer variable contains a memory address that points to another variable. To print the memory address stored in pointers and non-pointer variables using the %p conversion specifier is used #include <stdio.h> Output: p = 0022FF2C int main(void) { int a=10, *p; p=&a; printf(“n p = %p”, p); return 0; }
  • 18.
    Indirection Operator andDereferencing • The primary use of a pointer is to access and, if appropriate, change the value of the variable that the pointer is pointing to • The other pointer operator available in C is ‘*’, called the ‘value at address’ operator. • It returns the value stored at a particular address • The value at address operator is also called indirection operator or dereference operator
  • 19.
    Indirection Operator andDereferencing (cntd) In the following program, the value of the integer variable num is changed twice. #include <stdio.h> int main() { int num = 5; int *iPtr = &num; printf(“n The value of num is %d”, num); num = 10; printf(“n The value of num after num = 10 is: %d”, num); *iPtr = 15; printf(“n The value of num after *iPtr = 15 is: %d”, num); return 0; }
  • 20.
    Indirection Operator andDereferencing (cntd) • The second change should be familiar, by the direct assignment of a value to num, such as num=10 • However, the third change is accomplished in a new way, by using the indirection operator • *iPtr = 15; • The indirection operator is an asterisk, the same asterisk that is used to declare the pointer or to perform multiplication • However, in this statement the asterisk is not being used in a declaration or to perform multiplication
  • 21.
    Addition Using Pointers #include<stdio.h> int main() { int a,b,c; int *pa,*pb,*pc; pa=&a; pb=&b; pc=&c; printf(“n ENTER THE FIRST NUMBER:”); scanf(“%d”,pa); printf(“n ENTER THE SECOND NUMBER:”); scanf(“%d”,pb); *pc=*pa+*pb; printf(“n SUM IS %d”,*pc); return 0; }
  • 22.
    VOID POINTER • Avoid pointer is a special type of pointer • It can point to any data type, from an integer value or a float to a string of characters • The limitation is that the pointed data cannot be referenced directly • type casting or assignment must be used to turn the void pointer to a pointer of a concrete data type to which we can refer.
  • 23.
    VOID POINTER Example: #include <stdio.h> intmain() { int a=5, double b=3.1415; void *vp; vp=&a; printf(“n a= %d”, *((int *)vp)); vp=&b; printf(“n a= %d”, *((double *)vp)); return 0; }
  • 24.
    NULL POINTER • Anull pointer is a special pointer that points nowhere • That is, no other valid pointer to any other variable or array cell or anything else will ever be equal to a null pointer • The null pointer in the program is assigning with a keyword NULL, which is defined by several standard header files, including <stdio.h>, <stdlib.h>, and <string.h>
  • 25.
    NULL POINTER (cntd) #include<stdio.h> int main() { int *p; p = NULL; printf(“n The value of p is %u”, p); return 0; }
  • 26.
  • 27.
    USE OF POINTERS(cntd) Call by Reference
  • 28.
    Passing pointers tofunctions C programming allows passing a pointer to a function. To do so, simply declare the function parameter as a pointer type
  • 29.
    Passing pointers tofunctions (cntd) #include <stdio.h> void salaryhike(int *var, int b) { *var = *var+b; } int main() { int salary=0, bonus=0; printf("Enter the employee current salary:"); scanf("%d", &salary); printf("Enter bonus:"); scanf("%d", &bonus); salaryhike(&salary, bonus); printf("Final salary: %d", salary); return 0; } Enter the employee current salary:10000 Enter bonus:2000
  • 30.
    Pointers and onedimensional arrays • Pointers and arrays are inseparably related, but they are not synonymous. • An array is a non-empty set of sequentially indexed elements having the same type of data. Each element of an array has a unique identifying index number. • The array a is laid out in memory as a contiguous block, as shown. int a[]={10, 20, 30, 40, 50};
  • 31.
    • Array notationis a form of pointer notation. • The name of an array is the beginning address of the array, called the base address of the array. • The array name is referred to as an address constant. • Both array and &array would give the base address of the array, but the only difference is under ANSI/ISO Standard C, &array yields a pointer, of type pointer to- array of-the data type to the entire array. #include <stdio.h> int main() { int a[]={10, 20, 30, 40, 50}; printf(“%u %u”, a, &a[0]); return 0; } Output: 2147478270 2147478270
  • 32.
    • With thename of the array actually being a constant that represents a memory address, the name of the array can be used as a pointer and an integer value can be used to represent an offset from the base address. • An element of the array a is addressed as a[i] and the address of the ith element of the array a is given by &a[i]=a + i size of the type pointed to by a. • The expression a + i (with integer i) means the address of the ith element beyond the one a points to. This is known as scaling. • As indirection operator ‘*’ implies value at address, a[i] is equivalent to *(a+i).
  • 33.
    Example #include <stdio.h> int main() { inta[]={10, 20, 30, 40, 50}; int i; for(i=0;i<5;i++) { printf("n %d", a[i]); printf("n %d",*(a+i)); printf("n %d", &a[i]); } return 0; } Output: 10 10 1011568592 20 20 1011568596 30 30 1011568600 40 40 1011568604 50 50 1011568608
  • 34.
    • All thefollowing four expressions are the same when their addresses are considered. a[i], *(a + i), *(i + a), i[a] • In the expression a[i], i must be an integer. The other may either be an array name or a pointer. • For any one-dimensional array a and integer i, the following relationships are always true. 1. &a[0] == a 2. &a[i] == a + i 3. a[i] == *(a + i) 4. (&a[i] - &a[j]) == (i - j)
  • 35.
    • A pointervariable (of the appropriate type) can also be used to initialize or point to the first element of the array. Then it can also be used as above.
  • 36.
    • Pointers andarrays are so closely related that their notation can be interchanged such that the following terms are identical if p contains the value of a. • a[i] • *(a + i) • *(p + i) • p[i] where i=0,1,2,...(N–1). N is the size of the array.
  • 37.
    This equivalence doesnot mean that arrays and pointers are the same (they are, in fact, quite different) but that they can be used in related ways, and that certain operations may be used between them. These operations are as follows. • The first such operation is that it is possible to (apparently) assign an array to a pointer. int a[10]; int *p; p = a; C defines the result of this assignment to be that p receives a pointer to the first element of a. In otherwords, p = &a[0];
  • 38.
    • The secondaspect of the equivalence is that the array subscripting notation [i] can be applied on pointers,too. p[3] can be written as *(p + 3). The pointer to an array does not always point to the first element of the array. It can point to any element of the array. For example, int a[]={10,20,30,40,50}; int *p; p = a + 3; can also be written as follows p = &a[0] + 3; which, in turn, gives the same result as p = &a[3];
  • 41.
    Operations on Pointers •If p is declared as a pointer variable of any type and it has been initialized properly, then, just like a simple variable,any operation can be performed with *p. • Because *implies value at address, working with *p means working with the variable whose address is currently held by p. The only valid operations on pointers are as follows. • Assignment of pointers to the same type of pointers. • Adding or subtracting a pointer and an integer. • Subtracting or comparing two pointers. • Incrementing or decrementing the pointers. • Assigning the value 0 to the pointer variable and comparing 0 with the pointer.
  • 42.
    Assignment Pointers with theassignment operators can be used if thefollowing conditions are met. • The left-hand operand is a pointer and the right-hand operand is a null pointer constant. • One operand is a pointer to an object of incompatible type and the other is a pointer to void. • Both the operands are pointers to compatible types.
  • 43.
    #include <stdio.h> int main() { inti=5; int *ip; void *vp; ip = &i; vp = ip; //printf(“n *vp= %d”,*vp); —————— ERROR ip = vp; printf(“n *ip= %d”,*ip); return 0; } This program gives an error in the first printf statement stating ‘not an allowed type’ because no type is associated with a void pointer. • The right version of this program is as follows. #include <stdio.h> int main() { int i=5; int *ip; void *vp; ip = &i; vp = ip; printf(“n *vp= %d”,*((int *)vp)); ip = vp; printf(“n *ip= %d”,*ip); return 0; } Output: *vp=5 *ip=5
  • 44.
    Addition or Subtractionwith Integers • a ‘+’ between a pointer and an integer does the same offset computation as explained earlier, but leaves the result as a pointer. • We can add a value to the pointer variable. The formula of adding value to pointer is given below: new_address= current_address + (number * size_of(da ta type))
  • 45.
    #include<stdio.h> int main(){ int number=50; int*p;//pointer to int p=&number; //stores the address of number variable printf("Address of p variable is %u n",p); p=p+3; //adding 3 to pointer variable printf("After adding 3: Address of p variable is %u n",p); return 0; }
  • 46.
    Output: Address of pvariable is 3214864300 After adding 3: Address of p variable is 3214864312 • As you can see, the address of p is 3214864300. But after adding 3 with p variable, it is 3214864312, i.e., 4*3=12 increment. Since we are using 64-bit architecture, it increments 12.
  • 47.
    Consider the followingtwo versions of same program. (a) #include <stdio.h> int main(void) { int a[] = {10, 12, 6, 7, 2}; int i; int sum = 0; for(i=0; i<5; i++) { sum += a[i]; } printf(“%dn”, sum); return 0; } (b) #include <stdio.h> int main(void) { int a[] = {10, 12, 6, 7, 2}; int i; int sum = 0; for(i=0; i<5; i++) { sum += *(a + i); } printf(“%dn”, sum); return 0; }
  • 48.
    • Therefore, expressionscan add (or subtract, which is equivalent to adding negative values) integral values to the value of a pointer to any object type. The result has the type of the pointer and if n is added, then the result points n array elements away from the pointer.
  • 49.
    This is atypical string-processing function. • Pointer arithmetic and dereferencing are used to search for various characters or patterns
  • 50.
    Using p++ is apointer to an ment in an array, then 1) points to the next ment in the array. e statement p++ can be d to step a pointer er the elements in an ay. #include <stdio.h> int main(void) { int a[] = {10, 12, 6, 7, 2}; int i; int sum = 0; int *p; p = a; for(i=0; i<5; i++) { sum += *p; p++; } printf(“%dn”, sum); return 0; }
  • 51.
    It is possibleto traverse an array starting from a pointer to any element in the array. Consider the following program. /* initialize ptr to point to element arr[3] */ ptr = &arr[3]; *ptr = 1.0; /* arr[3] = 1.0 */ *(ptr - 1) = 0.9; /* arr[2] = .9 */ *(ptr + 1) = 1.1; /* arr[4] = 1.1 */ /* initialize iptr in the same way */ iptr = &a[3]; *iptr = 0; *(iptr - 1) = -1; *(iptr + 1) = 2; for(i = 0; i < N; i++) { printf(“arr[%d] = %f”, i, *(arr + 1)); printf(“a[%d] = %dn”, i, a[i]); return 0; } } #include <stdio.h> #defi ne N 5 int main() { float arr[N], *ptr; int *iptr, a[N], i; /* initialize */ for(i = 0; i < N; i++) { arr[i] = 0.3; a[i] = 1; }
  • 52.
    • arr[0] =0.300000 a[0] = 1 • arr[1] = 0.300000 a[1] = 1 • arr[2] = 0.900000 a[2] = -1 • arr[3] = 1.000000 a[3] = 0 • arr[4] = 1.100000 a[4] = 2
  • 53.
    C Pointer Subtraction •Like pointer addition, we can subtract a value from the pointer variable. Subtracting any number from a pointer will give an address. The formula of subtracting value from the pointer variable is given below: new_address= current_address (number * size_of(dat a type))
  • 54.
    #include<stdio.h> int main(){ int number=50; int*p;//pointer to int p=&number;//stores the address of number variable printf("Address of p variable is %u n",p); p=p-3; //subtracting 3 from pointer variable printf("After subtracting 3: Address of p variable is %u n",p); return 0; } Output: Address of p variable is 3214864300 After subtracting 3: Address of p variable is 3214864288
  • 55.
  • 56.
    Increment operator #include <stdio.h> intmain() { int A[] = {10, 20, 30, 40, 50}; int *p, i; p = A; printf(“*p : %inn”, *p); i = *(p++); printf(“i is: %in”, i); printf(“*p is: %inn”, *p); i = (*p)++; printf(“i is: %in”, i); printf(“*p is: %inn”, *p); i = *(++p); printf(“i is: %in”, i); printf(“*p is: %inn”, *p); i = ++(*p); printf(“i is: %in”, i); printf(“*p is: %inn”, *p); return 0; } Output: *p : 10 i is : 10 *p is: 20 i is: 20 *p is: 21 i is: 30 *p is: 30 i is: 31 *p is: 31
  • 57.
    Decrement operator #include <stdio.h> intmain(void) { int a[] = {10, 20, 30, 40, 50}; int i, *p; p=a+4; for(i=4; i>=0; i––) printf(“%dn”, *(p-i)); return 0; } Output: 10 20 30 40 50
  • 58.
    Subtraction of Pointers •For example, one might write p2 = p1 + 3; Applying a little algebra, p2 - p1 = 3 Here both p1 and p2 are pointers pointing to the elements of the same array. From this it can be concluded that the two pointers are subtracted, as long as they point into the same array. #include <stdio.h> int main() { double a[2],*p,*q; p=a; q=p+1; printf(“%dn”,q – p); return 0; } Output: 1 Given two pointers p and q of the same type, the difference p – q is an integer k such that adding k to q yields p.
  • 59.
    Subtraction of Pointers •To print the number of bytes resulting from q- p, each pointer may be typecast. #include <stdio.h> int main() { double a[2],*p,*q; p=a; q=p+1; printf(“%dn”,(int)q-(int)p); return 0; } Output: 8
  • 60.
    Comparing Pointers • Callows pointers to be compared with each other. If two pointers compare equal to each other, then they point to the same thing, whether it is an object or the non-existent element of the end of an array • If two pointers point to the same thing, then they compare equal to each other. • The relational operators >, <=, and so on give the result that would be expected if the pointers point to the same array: if one pointer compares less than another, then it points nearer to the front of the array.
  • 61.
    #include <stdio.h> int main(void) { inta[] = {10, 20, 30, 40, 50}; int i, *p; for(p=a; p<=a+4; p++) printf(“%dn”, *p); return 0; } Output: 10 20 30 40 50
  • 62.
    The following programwill print the line in reverse order.. #include <stdio.h> #include <string.h> int main() { char a[50]; void reverse(char *); printf(“n Enter the string:”); gets(a); reverse(a); printf(“nAfter reversing the string is :n”); puts(a); return 0; } void reverse(char *string) { char *lp = string; /* left pointer */ char *rp = &string[strlen(string)-1]; /* right pointer */ char tmp; while(lp < rp) { tmp = *lp; *lp = *rp; *rp = tmp; lp++; rp––; } } Output: Enter the string:manas After reversing the string is: sanam
  • 63.
  • 64.
    DYNAMIC MEMORY ALLOCATION •An array is a collection of a fixed number of values. Once the size of an array is declared, you cannot change it. • Sometimes the size of the array you declared may be insufficient. • To solve this issue, you can allocate memory manually during run-time. • This is known as dynamic memory allocation in C programming.
  • 65.
    To allocate memorydynamically, library functions are malloc(), calloc(), realloc() and free() are used. These functions are defined in the <stdlib.h> header file. malloc() allocates single block of requested memory. calloc() allocates multiple block of requested memory. realloc() reallocates the memory occupied by malloc() or calloc() functions. free() frees the dynamically allocated memory.
  • 66.
    DYNAMIC MEMORY ALLOCATION staticmemory allocation dynamic memory allocation memory is allocated at compile time. memory is allocated at run time. memory can't be increased while executing program. memory can be increased while executing program.
  • 67.
    C malloc() • Thename "malloc" stands for memory allocation. • The malloc() function reserves a block of memory of the specified number of bytes. • And, it returns a pointer of void which can be casted into pointers of any form. • Syntax of malloc() ptr = (castType*) malloc(size); ptr = (float*) malloc(100 * sizeof(float)); The above statement allocates 400 bytes of memory. It's because the size of float is 4 bytes. And, the pointer ptr holds the address of the first byte in the allocated memory.
  • 68.
    C calloc() • Thename "calloc" stands for contiguous allocation. • The malloc() function allocates memory and leaves the memory uninitialized. • Whereas, the calloc() function allocates memory and initializes all bits to zero. • Syntax of calloc() ptr = (castType*)calloc(n, size); ptr = (float*) calloc(25, sizeof(float)); The above statement allocates contiguous space in memory for 25 elements of type float.
  • 69.
    C free() • Dynamicallyallocated memory created with either calloc() or malloc() doesn't get freed on their own. You must explicitly use free() to release the space. • Syntax of free() free(ptr); This statement frees the space allocated in the memory pointed by ptr.
  • 70.
    C realloc() • Ifthe dynamically allocated memory is insufficient or more than required, you can change the size of previously allocated memory using the realloc() function. • Syntax of realloc() ptr = realloc(ptr, x); Here, ptr is reallocated with a new size x.
  • 71.
    Example 1: malloc()and free() Program to calculate the sum of n numbers entered by the user #include <stdio.h> #include <stdlib.h> int main() { int n, i, *ptr, sum = 0; printf("Enter number of elements: "); scanf("%d", &n); ptr = (int*) malloc(n * sizeof(int)); // if memory cannot be allocated if(ptr == NULL) { printf("Error! memory not allocated."); exit(0); } printf("Enter elements: "); for(i = 0; i < n; ++i) { scanf("%d", ptr + i); sum += *(ptr + i); } printf("Sum = %d", sum); // deallocating the memory free(ptr); return 0; }
  • 72.
    Example 2: calloc()and free() // Program to calculatethe sum of n numbers entered by the user #include <stdio.h> #include <stdlib.h> int main() { int n, i, *ptr, sum = 0; printf("Enternumber of elements: "); scanf("%d", &n); ptr = (int*) calloc(n, sizeof(int)); if(ptr== NULL) { printf("Error!memory not allocated."); exit(0); } printf("Enter elements: "); for(i = 0; i < n; ++i) { scanf("%d", ptr + i); sum += *(ptr + i); } printf("Sum = %d", sum); free(ptr); return 0; }
  • 73.
    Example 3: realloc() #include<stdio.h> #include <stdlib.h> int main() { int *ptr, i , n1, n2; printf("Enter size: "); scanf("%d", &n1); ptr = (int*) malloc(n1 * sizeof(int)); printf("Addresses of previously allocated memory: "); for(i = 0; i < n1; ++i) printf("%un",ptr + i); printf("nEnter the new size: "); scanf("%d", &n2); // rellocatingthe memory ptr = realloc(ptr, n2 * sizeof(int)); printf("Addresses of newly allocatedmemory: "); for(i = 0; i < n2; ++i) printf("%un",ptr + i); free(ptr); return 0; } Output: Enter size: 2 Addresses of previously allocated memory:26855472 26855476 Enter the new size: 4 Addresses of newly allocated memory:26855472 26855476 26855480 26855484
  • 74.
    The four functionsof interest are as follows: • void* malloc(size_t size): Request a contiguous block of memory of the given size in the heap. malloc() returns a pointer to the heap block or NULL if the request is not satisfied. • calloc(): works like malloc, but initializes the memory to zero if possible. The prototype is void * calloc(size_t count, size_t eltsize) This function allocates a block long enough to contain an array of count elements, each of size eltsize. Its contents are cleared to zero before calloc returns.
  • 75.
    • void free(void*block): free() takes a pointer to a heap block earlier allocated by malloc() and returns that block to the heap for reuse. • void* realloc(void* block, size_t size): Take an existing heap block and try to reallocate it to a heap block of the given size which may be larger or smaller than the original size of the block
  • 76.
    Example for Malloc() #include<stdlib.h> #include <stdio.h> int main() { int * ip; double * dp; fl oat * fp1; fl oat * fp2; ip = (int *) malloc(sizeof(int)); if(ip == NULL) { printf(“out of memoryn”); exit(-1); } dp =(double *) malloc(sizeof(double)); if(dp == NULL) { printf(“out of memoryn”); exit(-1); } fp1 =(fl oat *) malloc(sizeof(fl oat)); if(fp1 == NULL) { printf(“out of memoryn”); exit(-1); } fp2 = (fl oat *) malloc(sizeof(fl oat)); if(fp2 == NULL) { printf(“out of memoryn”); exit(-1); } *ip = 42; *dp = 3.1415926; *fp1 = -1.2; *fp2 = 0.34; printf(“ip: address %d; contents %dn”, (int)ip, *ip); printf(“dp: address %d; contents %fn”, (int)dp, *dp); printf(“fp1: address %d; contents %fn”, (int) fp1, *fp1); printf(“fp2: address %d; contents %fn”, (int fp2, *fp2); return 0; }
  • 77.
    Output: • ip: address133792; contents 42 • dp: address 133808; contents 3.141593 • fp1: address 133824; contents -1.200000 • fp2: address 133840; contents 0.340000