Pointers in C
Pointers in C
Pointers in C
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
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
2408
3456
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;
if(ptr)
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);
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]); }
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
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
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++;
EXPLANATION:
a 5 2000
5 2012
6 2012
2000
b 8 2004 main() y
8 2004
8 2016 fun()
9 2016 fun()
main()
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)++;
5 2000
x 2000 2012
6 2000
8 2004
2004 2016
9 2004 main()
main()
fun()
Example: int *fun(int); void main() { int i=10,*p; p=fun(i); printf(The value =%d,*p); }
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
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()
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
Realloc()
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
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