POINTER
POINTER
Pointers are variables that hold address of another variable of same data type.
Pointers are one of the most distinct and exciting features of C language. It provides power
and flexibility to the language.
A pointer is a variable whose value is the address of another variable, i.e., direct address of
the memory location. Like any variable or constant, you must declare a pointer before using it
to store any variable address. The general form of a pointer variable declaration is −
type *var-name;
Here, type is the pointer's base type; it must be a valid C data type and var-name is the name
of the pointer variable. The asterisk * used to declare a pointer is the same asterisk used for
multiplication. However, in this statement the asterisk is being used to designate a variable as
a pointer. Take a look at some of the valid pointer declarations −
The actual data type of the value of all pointers, whether integer, float, character, or
otherwise, is the same, a long hexadecimal number that represents a memory address. The
only difference between pointers of different data types is the data type of the variable or
constant that the pointer points to.
Features/Advantages –
Concept of Pointer
Whenever a variable is declared, system will allocate a location to that variable in the
memory, to hold value. This location will have its own address number.
Let us assume that system has allocated memory location 80F for a variable a.
int a = 10 ;
We can access the value 10 by either using the variable name a or the address 80F. Since the
memory addresses are simply numbers they can be assigned to some other variable. The
variable that holds memory address are called pointer variables. A pointer variable is
therefore nothing but a variable that contains an address, which is a location of another
variable. Value of pointer variable will be stored in another memory location.
Reference operator(&)
Output
Value: 5
Address: 2686778
Pointer variable or simply pointer are the special types of variables that holds memory
address rather than data, that is, a variable that holds address value is called a pointer variable
or simply a pointer.
Declaration of Pointer
data_type* pointer_variable_name;
int* p;
int a,*p;
a = 10;
p = &a;
There are few important operations which we will do with the help of pointers very
frequently.
(c) Finally access the value at the address available in the pointer variable. This is done by
using unary operator * that returns the value of the variable located at the address specified
by its operand. Following example makes use of these operations:
#include <stdio.h>
int main ()
{
int var = 20; /* actual variable declaration */
int *ip; /* pointer variable declaration */
return 0;
}
When the above code is compiled and executed, it produces result something as follows:
Pointers are flexible. We can make the same pointer to point to different data variable in
different statements. Example
int x,y,z,*ptr;
ptr=&x;
ptr=&y;
ptr=&z;
We can also use the different pointer to point to the same data variable. For example
int x;
int *p1=&x;
int *p2=&x;
int *p3=&x;
Chain of Pointer –
It is possible to make a pointer to point to another pointer, thus creating a chain of pointers
as follows –
P2-------p1---------------variable’s value
Here, the pointer variable p2 contains the address of the pointer variable p1, which points
to the location that contain the desired value. This is known as “MULTIPLE INDIRECTION”
A variable that is pointer to a pointer must be declared using additional indirection operator
symbols in front of the name example –
int **p2;
This declaration tells the compiler that p2 is a pointer to pointer of int type. Remember, the
pointer p2 is not a pointer to an int, but rather a pointer to an int pointer.
p1=p1+2;
p1=p1+10;
will cause the pointer p1 to point to the next value of its type. For example if p1 is an integer
pointer with an initial value, say 2000 then after the operation p1=p1+1, the value of p1 will
be 2002 and not 2001.
It means, when we increment a pointer, its value is increase by the length of the data type
that it points to. This length is called the SCALE FACTOR.
The process of calling function using a pointer to pass the addresses of variable is known as
“call by reference”.
And the process of passing the actual value of variable is known as “Call by value”.
Example –
main()
int *p;
printf(“%d”,*p);
If(*x>*y)
return(x); //address of a
else
return(y); //address of b
}
NULL Pointers in C
It is always a good practice to assign a NULL value to a pointer variable in case you do not
have exact address to be assigned. This is done at the time of variable declaration. A pointer
that is assigned NULL is called a null pointer.
The NULL pointer is a constant with a value of zero defined in several standard libraries.
Consider the following program:
#include <stdio.h>
int main ()
{
int *ptr = NULL;
return 0;
}
When the above code is compiled and executed, it produces following result:
C - Pointer arithmetic
A pointer in c is an address, which is a numeric value. Therefore, you can perform arithmetic
operations on a pointer just as you can on a numeric value. There are four arithmetic
operators that can be used on pointers: ++, --, +, and -
To understand pointer arithmetic, let us consider that ptr is an integer pointer which points to
the address 1000. Assuming 32-bit integers, let us perform the following arithmetic operation
on the pointer −
ptr++
After the above operation, the ptr will point to the location 1004 because each time ptr is
incremented, it will point to the next integer location which is 4 bytes next to the current
location. This operation will move the pointer to the next memory location without impacting
the actual value at the memory location. If ptr points to a character whose address is 1000,
then the above operation will point to the location 1001 because the next character will be
available at 1001.
Incrementing a Pointer
We prefer using a pointer in our program instead of an array because the variable pointer can
be incremented, unlike the array name which cannot be incremented because it is a constant
pointer. The following program increments the variable pointer to access each succeeding
element of the array −
#include <stdio.h>
int main () {
return 0;
}
When the above code is compiled and executed, it produces the following result −
Decrementing a Pointer
The same considerations apply to decrementing a pointer, which decreases its value by the
number of bytes of its data type as shown below −
#include <stdio.h>
int main () {
return 0;
}
When the above code is compiled and executed, it produces the following result −
Pointer Comparisons
Pointers may be compared by using relational operators, such as ==, <, and >. If p1 and p2
point to variables that are related to each other, such as elements of the same array, then p1
and p2 can be meaningfully compared.
The following program modifies the previous example − one by incrementing the variable
pointer so long as the address to which it points is either less than or equal to the address of
the last element of the array, which is &var[MAX - 1] −
#include <stdio.h>
int main () {
return 0;
}
When the above code is compiled and executed, it produces the following result −
Array of pointers
#include <stdio.h>
return 0;
}
When the above code is compiled and executed, it produces the following result −
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200
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. Following is the declaration of an array of
pointers to an integer −
int *ptr[MAX];
It declares ptr as an array of MAX integer pointers. Thus, each element in ptr, holds a pointer
to an int value. The following example uses three integers, which are stored in an array of
pointers, as follows −
#include <stdio.h>
int main () {
return 0;
}
When the above code is compiled and executed, it produces the following result −
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200
Pointer to Structure
Like we have array of integers, array of pointer etc, we can also have array of structure
variables. And to make the use of array of structure variables efficient, we use pointers of
structure type. We can also have pointer to a single structure variable, but it is mostly used
with array of structure variables.
struct Book
{
char name[10];
int price;
}
int main()
{
struct Book a; //Single structure variable
struct Book* ptr; //Pointer of Structure type
ptr = &a;
To access members of structure with structure variable, we used the dot . operator. But when
we have a pointer of structure type, we use arrow -> to access structure members.
struct Book
{
char name[10];
int price;
}
int main()
{
struct Book b;
struct Book* ptr = &b;
ptr->name = "Dan Brown"; //Accessing Structure Members
ptr->price = 500;
}
Pointer in function parameter list is used to hold address of argument passed during function
call. This is also known as call by reference. When a function is called by reference any
change made to the reference variable will effect the original variable.
Example: Sorting an array using Pointer
#include <stdio.h>
#include <conio.h>
void sorting(int *x, int y);
void main()
{
int a[5],b,c;
clrscr();
printf("enter 5 nos");
for(b=0; b<5; b++)
{
scanf("%d",&a[b]);
}
sorting(a, 5);
getch();
}
A function can also return a pointer to the calling function. In this case you must be careful,
because local variables of function doesn't live outside the function, hence if you return a
pointer connected to a local variable, that pointer be will pointing to nothing when function
ends.
#include <stdio.h>
#include <conio.h>
int* larger(int*, int*);
void main()
{
int a=15;
int b=92;
int *p;
p=larger(&a, &b);
printf("%d is larger",*p);
}
1. Either use argument with functions. Because argument passed to the functions are declared
inside the calling function, hence they will live outside the function called.
2. Or, use static local variables inside the function and return it. As static variables have a
lifetime until main() exits, they will be available througout the program.
Pointer to functions
type (*pointer-name)(parameter);
Example :
int (*sum)(); //legal declaraction of pointer to function
int *sum(); //This is not a declaraction of pointer to function
A function pointer can point to a specific function when it is assigned the name of the
function.
s is a pointer to a function sum. Now sum can be called using function pointer s with the list
of parameter.
s (10, 20);
#include <stdio.h>
#include <conio.h>
int main( )
{
int (*fp)(int, int);
fp = sum;
int s = fp(10, 15);
printf("Sum is %d",s);
getch();
return 0;
}
Output : 25
*ptr++ means
++*ptr means
char * and char [] both are used to access character array, Though functionally both are same
, they are syntactically different. See how both works in order to access string.
Consider following sample example for storing and accessing string using character array –
In the example – String “Hello” is stored in Character Array ‘a’. Character array is used to
store characters in Contiguous Memory Location. It will take Following Form after
Initialization. We have not specified Array Size in this example.Each array location will get
following values –
a[0] = 'H'
a[1] = 'E'
a[2] = 'L'
a[3] = 'L'
a[4] = 'O'
a[5] = '\0'
Suppose we have to find out a[3] then firstly compiler will check whether ‘a’ is Array or
Pointer ? If ‘a’ is Array Variable then It starts at the location “a”, goes three elements past it,
and returns the character there.In this method element is accessed Sequentially
String “Hello” will be stored at any Anonymous location in the form of array. We even don’t
know the location where we have stored string, However String will have its starting address.
Syntax of Char *a :
char *a = "HELLO";
We have declared pointer of type character i.e pointer variable is able to hold the address of
character variable. Now Base address of anonymous array is stored in character pointer
variable. ‘a’ Stores Base Address of the Anonymous Array [Unknown Array]
Typedef-
The C programming language provides a keyword called typedef which you can use to give a
type a new name. Following is an example to define a term BYTE for one-byte numbers:
After this type definitions, the identifier BYTE can be used as an abbreviation for the type
unsigned char, for example:.
#include <stdio.h>
#include <string.h>
int main( )
{
Book b1;
return 0;
}
Output-
Book title : C Programming
Book author : Nuha Ali
Book subject : C Programming Tutorial
Book book_id : 6495407
typedef vs #define
The #define is a C-directive which is also used to define the aliases for various data types
similar to typedef but with three differences:
The typedef is limited to giving symbolic names to types only where as #define can
be used to define alias for values as well, like you can define 1 as ONE etc.
The typedef interpretation is performed by the compiler where as #define
statements are processed by the pre-processor.
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int main( )
{
printf( "Value of TRUE : %d\n", TRUE);
printf( "Value of FALSE : %d\n", FALSE);
return 0;
}
Value of TRUE : 1
Value of FALSE : 0
self-referential structure-
A self referential structure is used to create data structures like linked lists, stacks, etc.
Following is an example of this kind of structure:
struct struct_name
{
datatype datatypename;
struct_name * pointer_name;
};
A self-referential structure is one of the data structures which refer to the pointer to (points)
to another structure of the same type. For example, a linked list is supposed to be a self-
referential data structure. The next node of a node is being pointed, which is of the same
struct type. For example,
In the above example, the listnode is a self-referential structure – because the *next is of the
type struct listnode.