Pointers in C . Some C programming tasks are performed more easily with pointers, and other tasks, such as dynamic memory allocation, cannot be performed without using pointers. So it becomes necessary to learn pointers to become a perfect C programmer. Let's start learning them in simple and easy steps.
As you know, every variable is a memory location and every memory location has its address defined which can be accessed using ampersand (&) operator, which denotes an address in memory. Consider the following example, which prints the address of the variables defined −
If you have a variable var in your program, &var will give you its address in the memory.
We have used address numerous times while using the scanf() function.
scanf("%d", &var);
Here, the value entered by the user is stored in the address of var variable. Let's take a working example.
#include <stdio.h>
int main()
{
 int var = 5;
 printf("var: %d\n", var);
 // Notice the use of & before var
 printf("address of var: %p", &var);
 return 0;
}
Output
var: 5
address of var: 2686778
What are Pointers?
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 −
int *ip; /* pointer to an integer */
double *dp; /* pointer to a double */
float *fp; /* pointer to a float */
char *ch /* pointer to a character */
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.
#include <stdio.h>
int main () {
int var = 20; /* actual variable declaration */
int *ip; /* pointer variable declaration */
ip = &var; /* store address of var in pointer variable*/
printf("Address of var variable: %x\n", &var );
/* address stored in pointer variable */
printf("Address stored in ip variable: %x\n", ip );
/* access the value using the pointer */
printf("Value of *ip variable: %d\n", *ip );
return 0;
}
Example: Working of Pointers
Let's take a working example.
#include <stdio.h>
int main()
{
int* pc, c;
c = 22;
printf("Address of c: %p\n", &c);
printf("Value of c: %d\n\n", c); // 22
pc = &c;
printf("Address of pointer pc: %p\n", pc);
printf("Content of pointer pc: %d\n\n", *pc); // 22
c = 11;
printf("Address of pointer pc: %p\n", pc);
printf("Content of pointer pc: %d\n\n", *pc); // 11
*pc = 2;
printf("Address of c: %p\n", &c);
printf("Value of c: %d\n\n", c); // 2
return 0;
}
Output
Address of c: 2686784
Value of c: 22
Address of pointer pc: 2686784
Content of pointer pc: 22
Address of pointer pc: 2686784
Content of pointer pc: 11
Address of c: 2686784
Value of c: 2
Relationship Between Arrays and Pointers
An array is a block of sequential data.
Let's write a program to print addresses of array elements.
#include <stdio.h>
int main() {
  int x[4];
  int i;
  for(i = 0; i < 4; ++i) {
   printf("&x[%d] = %p\n", i, &x[i]);
  }
  printf("Address of array x: %p", x);
  return 0;
}
Output
&x[0] = 1450734448
&x[1] = 1450734452
&x[2] = 1450734456
&x[3] = 1450734460
Address of array x: 1450734448
There is a difference of 4 bytes between two consecutive elements of array x. It is because the size of int is 4 bytes (on our compiler).
Notice that, the address of &x[0] and x is the same. It's because the variable name x points to the first element of the array.
From the above example, it is clear that &x[0] is equivalent to x. And, x[0] is equivalent to *x.
Similarly,
&x[1] is equivalent to x+1 and x[1] is equivalent to *(x+1).
&x[2] is equivalent to x+2 and x[2] is equivalent to *(x+2).
...
Basically, &x[i] is equivalent to x+i and x[i] is equivalent to *(x+i).
Example 1: Pointers and Arrays
#include <stdio.h>
int main() {
 int i, x[6], sum = 0;
 printf("Enter 6 numbers: ");
 for(i = 0; i < 6; ++i) {
 // Equivalent to scanf("%d", &x[i]);
   scanf("%d", x+i);
 // Equivalent to sum += x[i]
   sum += *(x+i);
 }
 printf("Sum = %d", sum);
 return 0;
}
When you run the program, the output will be:
Enter 6 numbers: 2
3
4
4
12
4
Sum = 29
Here, we have declared an array x of 6 elements. To access elements of the array, we have used pointers.
In most contexts, array names decay to pointers. In simple words, array names are converted to pointers. That's the reason why you can use pointers to access elements of arrays. However, you should remember that pointers and arrays are not the same.
Example 2: Arrays and Pointers
#include <stdio.h>
int main() {
 int x[5] = {1, 2, 3, 4, 5};
 int* ptr;
 // ptr is assigned the address of the third element
 ptr = &x[2];
 printf("*ptr = %d \n", *ptr);  // 3
 printf("*(ptr+1) = %d \n", *(ptr+1)); // 4
 printf("*(ptr-1) = %d", *(ptr-1)); // 2
 return 0;
}
When you run the program, the output will be:
*ptr = 3
*(ptr+1) = 4
*(ptr-1) = 2
In this example, &x[2], the address of the third element, is assigned to the ptr pointer. Hence, 3 was displayed when we printed *ptr.
And, printing *(ptr+1) gives us the fourth element. Similarly, printing *(ptr-1) gives us the second element.
Comments