Vous êtes sur la page 1sur 53

MODULE 3:POINTERS

WHAT

IS A POINTER? DECLARATION OF POINTER VARIABLE ASSIGNING ADDRESS TO A POINTER VARIABLE DEREFRRENCING POINTER VARIABLE POINTER TO POINTER POINTER AND 1D-ARRAY POINTER AND FUNCTIONS ARRAY OF POINTER DYNAMIC MEMORY ALLOCATION POINTER TO A STRUCTURE SELF REFERENCING STRUCTURE

A pointer is a variable that stores memory address. Like all other variables it also has a name, has to be declared and occupies some space in memory. It is called pointer because it points to a particular location in memory by storing the address of that location. Space occupied by pointer variable in the memory is equal for all types of pointers irrespective of there data type ,since all pointers holds address.

Some of the uses of pointers are: Accessing array elements Accessing dynamically allocated memory Implementing data structure like linked list, tree and graph

int

a = 10;
1000 10 1002 1004

How

to print the address

printf(Address of a is %u, &a);

Syntax: data_type *pname;

ASTERIK REQUIRED TO DEFINE A POINTER VARIABLE


EXAMPLE:

NAME OF POINTER VARIABLE

int *iptr; float *fptr; char *cptr1,*cptr2;

int *iptr;
o

Here iptr is a pointer that should point to variable of type int. Here iptr can be said as pointer to int float *fptr; Here fptr is a pointer that should point to variable of type float. Here iptr can be said as pointer to float

int *iptr; int i=10; Iptr=&i;


i 10 iptr 2408 USED TO DENOTE THE ADDRESS OF VARIABLE NOT THE CONTENT.

2408

3456

iptr holds the address of variable i.

We can initialize pointer at the time of declaration, but in this case the variable should be declared before the pointer. EXAMPLE: int i=10, *iptr=&i;

It is also possible to assign the value of one pointer variable to other,provided their basic type is same. EXAMPLE: int *p; int i=10, *iptr=&i; p=iptr;
o

pointer that points nothing is known as NULL POINTER. It contains the value 0.
memory address 0 has special significance, It signals that the pointer is not intended to point to an accessible memory location

The

#include<stdio.h> int main () { int *ptr = NULL; printf("The value of ptr is : %x\n", ptr );
return 0;

} OUTPUT: The value of ptr is 0

if(ptr)

OR if(ptr==NULL) /* succeeds if p is not null */ OR if(ptr != NULL) /* succeeds if p is null */

if(!ptr)

We can access a variable indirectly using pointers. For this we will use indirection operation (*). Example: int a=10; int *pa=&a;
*pa=20; is equivalent to a=20;

(*pa)++;
X=*pa+10; Printf(%d,*pa);

is equivalent to
is equivalent to is equivalent to

a++;
x=a+10; printf(%d,a);

NOTE: scanf(%d,&a); will be equivalent to scanf(%d,pa); Since &*pa=pa

ppa 3098 6874 int a=10; int *pa=&a; int **pa=&pa;

pa 2048 3098

a 10 2048

Here type of variable a is int,type of variable pa is (int *) or pointer to int, type of variable ppa is (int **) or pointer to pointer to int.

EXAMPLE
int a; int *pa; int **ppa; a = 10; /* take the address of var */ pa = &a; /* take the address of ptr using address of operator & */ ppa = &pa; /* take the value using ppa*/ printf("Value of var = %d\n", a ); printf("Value available at *pa = %d\n", *pa ); printf("Value available at **ppa = %d\n", **ppa);

OUTPUT:
Value of a= 10 Value available at *pa = 10 Value available at **ppa = 10 EXPLANATION: **ppa =>*(*ppa) =>*(pa) [since *ppa gives pa] =>a [since *pa gives a]

Main points for understanding the relation between pointer and array:
Elements of an array are stored in consecutive memory locations. The name of an array is a constant pointer that points to the 1st element of the array, i.e it stores the 1st(base) address of array. When a pointer variable is incrimented it points to the next location of its base type.

int arr[4]={5,10,15,20,25};
a[0] 5 2000 a[1] 10 2004 a[2] 15 2008 a[3] 20 2012 a[4] 25 2016

We can get the address of an element of array by applying & operator in front of subscripted variable name.
#include<stdio.h> main() { int a[5]={5,10,15,20,25}; int i; for(i=0;i<5;i++) { printf(value of a[%d]=%d\t,i,a[i]); printf(address of a[%d]=%u\t,i,&a[i]); }

a a+1 a+2 a+3 a+4

points to 0th element points to 1st element points to 2nd element points to 3rd element points to 4th element
value of 0th value of 1st value of 2nd value of 3rd value of 4th

&a[0] &a[1] &a[2] &a[3] &a[4]

2000 2004 2008 2012 2016

*a *(a+1) *(a+2) *(a+3) *(a+4)

element element element element element

a[0] 5 a[1] 10 a[2] 15 a[3] 20 a[4] 25

Program to print the value and address of elements of an array.


#include<stdio.h> void main() { int i,a[5]={5,10,15,20,25}; for(i=0;i<5;i++) { printf(value of a[%d]=%d\t,i,*(a+i)); printf(address of a[%d]=%u\t,i,a+i); } }

USING

POINTER ARITHMETIC C pointer is an address which is a numeric value. Therefore, you can perform arithmetic operations on a pointer just as you can a numeric value. There are four arithmetic operators that can be used on pointers: ++, --, +, and -

EXAMPLE OF POINTER ARITHMETIC #include <stdio.h> int main () { int a[5] = {10,15, 20,25}; int i, *ptr; /* let us have array address in pointer */ ptr = a; /* assigning base address of array to ptr*/ for ( i = 0; i < 5; i++) { printf("Address of var[%d] = %u\n", i, ptr ); printf("Value of var[%d] = %d\n", i, *ptr ); /* move to the next location */ ptr++; } return 0; }

OUTPUT:
Address of a[0] = 2000 Value of a[0] = 5 Address of a[1] = 2004 Value of a[1] = 10 Address of a[2] = 2008 Value of a[2] = 15 Address of a[3] = 2012 Value of a[2] = 20 Address of a[2] = 2016 Value of a[2] = 25

EXPLAINATION:
a[0]
5 2000 ptr 10

a[1]

a[2]
15 2008

a[3]
20 2012

a[4]
25 2016

2004

ptr points to the base address of array. ptr++ increase ptr by 1 integer address (i.e the next location in the array)

POINTER

COMPARISIONS Pointers may be compared by using relational operators, such as ==, <, and >.

EXAMPLE OF POINTER COMPARISONS #include <stdio.h> int main () { int var[] = {10, 100, 200}; int i, *ptr; /* let us have address of the first element in pointer */ ptr = var; i = 0; while ( ptr <= &var[i] ) { printf("Address of var[%d] = %u\n", i, ptr ); printf("Value of var[%d] = %d\n", i, *ptr ); /* point to the previous location */ ptr++; i++; } return 0; }

OUTPUT: Address of var[0] = 1000 Value of var[0] = 10 Address of var[1] = 1002 Value of var[1] = 100 Address of var[2] = 1004 Value of var[2] = 200
value address

10
100 200

1000
1002 1004

SOME TRICKS WITH POINTER ARITHMETIC:


What is the result of running the following code? void main() { int arr[] = {1, 2, 3}; int *ptr; ptr = arr; printf("arr[0] = %d, arr[1] = %d, arr[2] = %d, ptr = %u, *ptr = %d\n", arr[0], arr[1], arr[2], ptr, *ptr); *ptr++ = 10; printf("arr[0] = %d, arr[1] = %d, arr[2] = %d, ptr = %u, *ptr = %d\n", arr[0], arr[1], arr[2], ptr, *ptr); *++ptr = 20; printf("arr[0] = %d, arr[1] = %d, arr[2] = %d, ptr = %u, *ptr = %d\n", arr[0], arr[1], arr[2], ptr, *ptr); (*ptr)++; printf("arr[0] = %d, arr[1] = %d, arr[2] = %d, ptr = %u, *ptr = %d\n", arr[0], arr[1], arr[2], ptr, *ptr); }

ptr = arr

This will make the pointer ptr point to the first element in the array arr.

*ptr++ = 10
post-increment (++) has higher presedence than (*) operator, hence (++) will be applied first. Once its applied, it will not affect the value of ptr until the statement completes execution. ptr is still pointing to the first element of the array (arr[0]). Now, we apply the * operator to the ptr operand. This will dereference the pointer and will let us access the content it points to. Since its pointing to arr[0], *ptr = 10 will set the value of arr[0] to 10. After the statement completes execution, the pointer ptr is incremented and thus will point to the next element in the array (arr[1]).

*++ptr = 20
The increment operator (++) takes precedence over the dereference operator (*). Since this is a pre-increment operator, ++ptr will make the pointer point to the next element in the array arr[2]. *ptr = 20 will then set the value of arr[2] to 20.

(*ptr)++
*ptr will point us to arr[2] and thus running (*ptr)++ will increment the value of the integer that ptr is pointing to. So the value of arr[2] will be incremented by 1 once the statement completes execution and the pointer ptr will still point to arr[2]. If we try to compile (*ptr)++ = 0 we will get the following compilation error: error C2106: = : left operand must be l-value.

OUTPUT:
arr[0] = 1, arr[1] = 2, arr[2] = 3, ptr = 0043FE44, *ptr = 1 arr[0] = 10, arr[1] = 2, arr[2] = 3, ptr = 0043FE48, *ptr = 2 arr[0] = 10, arr[1] = 2, arr[2] = 20, ptr = 0043FE4C, *ptr = 20 arr[0] = 10, arr[1] = 2, arr[2] = 21, ptr = 0043FE4C, *ptr = 21

Argument to the function can be passed in 2 ways: Call by value Call by address CALL BY VALUE:
#include<stdio.h> Void main() { int a=5,b=8; printf(Before calling function, a=%d and b=%d,a,b); fun(a,b); printf(After calling function, a=%d and b=%d,a,b); } void fun(int x,int y) { x++; Y++;

printf(inside function, x=%d and y=%d,a,b); }

EXPLANATION:
a 5 2000

5 2012

6 2012

2000
b 8 2004 main() y

8 2004

8 2016 fun()

9 2016 fun()

main()

Before execution of function

After execution of function

Call by address:
#include<stdio.h> Void fun(int *x, int *y); Void main() { int a=5,b=8; printf(Before calling function, a=%d and b=%d,a,b); fun(&a,&b); printf(After calling function, a=%d and b=%d,a,b); } void fun(int *x,int *y) { (*x)++; (*Y)++;

printf(inside function, x=%d and y=%d,*x,*y); }

5 2000

x 2000 2012

6 2000

2000 2012 2004 2016 fun()

8 2004

2004 2016

9 2004 main()

main()

fun()

Before calling the function

After calling function

We can have functions that return a pointer.


Prototype syntax: data_type *function_name(arguments); Calling : Data_type *p; p=function_name(arguments);

Example: int *fun(int); void main() { int i=10,*p; p=fun(i); printf(The value =%d,*p); }

int *fun(int i) { i=i+10; return &i; }

OUTPUT: value =20

C programming language allows you to pass a pointer to a function. To do so, simply declare the function parameter as a pointer type. PROTOTYPE: int factorial(int *); DECLARATION: int factorial(int *ip) { //function body } CALLING int a = 10; int *p = &a; int f = factorial(p);

There

may be a situation when we want to maintain an array which can store pointers to an int or char or any other data type available.

DECLARATION:

int *ptr[10]; This declares ptr as an array of 10 integer pointers. Thus, each element in ptr, now holds a pointer to an int value.

#include <stdio.h> int main () { int var[] = {10, 100, 200}; int i, *ptr[MAX]; for ( i = 0; i < 3; i++) { ptr[i] = &var[i]; /* assign the address of integer. */ } for ( i = 0; i < 3; i++) { printf("Value of var[%d] = %d\n", i, *ptr[i] ); } return 0; }

OUTPUT:
Value of var[0] = 10 Value of var[1] = 100 Value of var[2] = 200

In fixed arrays the memory allocation is static in nature, which is allocated at compile time

Problems of using fixed size arrays:


Possibility

of OVERFLOW Wastage of Memory

Solution: DYNAMIC MEMORY ALLOCATION


Or memory allocated at runtime(at the time of execution) At run time we can: Allocate memory Deallocate memory

Malloc()

void* malloc(size_t size) request a contiguous block of memory of the given size. returns a pointer to that block or NULL if the request is not satisfied The type size_t is essentially an unsigned long that indicates how large a block is needed. Measured in bytes. Because the block pointer returned is void pointer a type casting is needed when storing the void pointer in a regular pointer.

Calloc()

void * calloc (size_t n, size_t size);


The first argument specifies number of elements to be reserved. The second argument specifies the size in bytes of one element. The function returns a pointer to the beginning of the allocated storage area in memory It contents are cleared to zero before calloc returns

calloc function is used to reserve space for dynamic arrays.

Realloc()

Void* realloc(void *block, size_t size);

First argument takes an existing block and try to reallocate it with the given size larger or smaller to the previous size. Second argument specifies the new size of the block. Realloc moves the old block bytes to new position in memory after reallocation. So the old pointer must also be changed with it.

Free(void

*block)

Takes a pointer allocated by malloc and frees that block for later reuse.
After freeing a memory block it could not be accessed anymore

S.N.
1

Function and Description


void *calloc(int num, int size); This function allocates an array of num elements each of which size in bytes will be size. void *malloc(int num); This function allocates an array of num bytes and leave them initialized. void *realloc(void *address, int newsize); This function re-allocates memory extending it upto newsize. void free(void *address); This function release a block of memory block specified by address.

You

can define pointers to structures in very similar way as you define pointer to any other variable as follows: struct structure_name *pointer_name ;

This line declares that the pointer pointer_name will point to a datatype of structure_name Now this pointer contains garbage value and it can now be used to point to a user defined type structure_name.

struct student { int roll; char name[20]; float marks; }; Struct student s1; Struct student *ptr; Ptr=&s1;
ptr

s1
name

state city

typedef struct Record { char name[21]; char city[21]; char state[3]; } Rec; Rec *r = (Rec *)malloc(sizeof(Rec));
name
r

state city

typedef struct Record { int data; struct Record *link; } Rec; 20 5430 Rec r1; Rec *ptr; 1000 ptr Ptr=&r1; 5430 Ptr->data=20; Ptr->link=(Rec *)malloc(sizeof(Rec));
1000

THANK YOU