A pointer is a very powerful and sophisticated feature provided in the C language. A variable defined in a program the compiler allocates a space in the memory to store its value. The number of bytes allocated to the variable depends on its type. For instance, a character is allocated 1 byte, an int is, in general, allocated 4 bytes, and a float is also allocated 4 bytes on a typical 32-bit system. The memory in RAM is grouped into bytes; each byte has 8 bits of memory. Bytes are sequentially numbered.
Thus, each byte is associated with a number which is its address. When a variable is declared, a block of memory is allocated to store its value. The address of a variable is the byte number of the first byte of the memory block allocated for value storage. The value of a pointer to the variable is also the address where the value is stored, i.e., its value is the byte number of the first byte of the memory block where the value of variable is stored. A pointer to a data item is nothing but the address of that data item. Address of a variable may be determined by application of address-of operator (&).We can store this address in a variable, called the pointer variable, and use it to manipulate that data item. For instance, let Marks be a variable of type int. On a 32-bit system, Marks would be allocated a memory block of size 4 bytes for storing its value.
Fig illustrates the concept of a pointer. Fig depicts two variables: an ordinary variable x of type int stored in memory location Ox1234 and a pointer variable px. The pointer variable px holds the address of variable x (which is an integer value) and is said to point to variable x. The type of this pointer variable is int*, i.e., a pointer to int. Although we can use any name for a pointer variable, the name px (which indicates pointer to x) is more meaningful.
It may be noted that as a C programmer, we do not need to know the actual address stored in a pointer variable in most situations. Moreover, the pointer variable may physically be present anywhere in main memory, either before the variable it points to or after it. Hence, an arrow is used as shown in Fig to show that a pointer variable points to a variable, i. e., it holds the address of that variable.
Note that Fig uses an integer variable x for the purpose of illustration. However, we can have a pointer pointing to variables of any type. The type of pointer which points to a variable of type T is T *. However, note that irrespective of the type of a pointer variable, it holds an integer value, the memory address of the variable it points to. Thus, in a particular environment, a pointer variable usually requires the same amount of memory irrespective of the type of data item it points to. This is usually two bytes on C compilers running on 16-bit operating systems such as MS DOS, e.g., Turbo C/C++1 and four bytes on 32-bit operating systems such as MS Windows and Linux, e.g., Dev-C++, Code::Blocks, GNU C/C++, etc.
we can manipulate the value of variable x, shown in Fig using pointer variable px and this is a very powerful feature, although it does not appear to be. After all, why should we manipulate variable x using pointer px when we can directly manipulate it? There are some compelling situations where we cannot perform such manipulations. For example, if we are required to manipulate, from within a function, the data items local to some other function, we must use pointers.
It may be noted that during its lifetime, a pointer variable need not always point to the same variable. We can manipulate the pointer itself so that it points to other variables. This is particularly useful while working with arrays. For example, the ++ operator increments the address stored in a pointer such that it points to the next element in that array. Similarly, the — operator decrements a pointer so that it points to the previous array element. The use of pointers with arrays often leads to concise and efficient code.
There are several advantages in using pointers, some of which are listed below.
1. Pointers enable us to use call by reference mechanism. This enables changes to the formal parameters within a function to be reflected in arguments in the function call. Thus, the modified values are passed back to the calling function.
2. The use of pointers for manipulations of arrays and strings often leads to concise and efficient programs.
3. Using pointers, we can construct advanced data structures such as linked lists, trees, graphs, etc. to store and manipulate complex data. The use of such advanced data structures often leads to efficient programs.
4. Pointers permit more efficient use of memory, which is a very valuable and limited resource, using a technique called dynamic memory management.
5. Void pointers and pointers to functions enable us to write powerful generic functions that work with different data types.
6. Pointers also enable the command-line arguments to be passed to a program.
Illustrates pointers and the address-of operator (&)
1 2 3 4 5 6 7 8 9 10 11 12 | #include<stdio.h> int main () { int y = 78; int *ptry = &y, *P; clrscr(); P = &y; printf ( "Address of y = %p\n" , &y); printf ( "ptry = %p\tP = %p\n" , ptry, P); printf ( "*ptry = %d\n*P = %d\n" , *ptry, *P); printf ( "*&y = %d \n" , *&y); return 0; } |
The output is as given below
The first line of the output gives the address of variable y. Two pointers *ptry and *Pare declared for y. The values of ptry and Pare same and equal to the address of y. In the third and fourth lines of the output, the value of y is obtained by dereferencing ptry and P. Both give the value of y = 78. The last line of the output shows that the operator(*) and the operator (&) are opposite to each other.