Pointers in C Language

Pointer is called the soul of c. The importance of pointer can be understood by the fact that most of the device driver or embedded system program are created in c. Pointer makes the c most usable and flexible programming. Due to the availability of the pointer, it is possible to write a program such as a device driver. These programs are also known as the device driver. To understand the pointer we have to first understand the memory organization of any variable. The following figure shows the fact.
Memory map of a variable

Whenever a variable stored in memory it occupies some memory space and every memory space has a unique number associated with it known as an address. Every byte in member has a different address. If we create an integer variable and suppose it occupy 2 bytes in memory, then two addresses are associated with it but its first address is enough to access it. so the address of next bytes is less useful.

To access the address of a variable & (Address of) operator is used. To understand the fact lets take an example.

Program: Use of Address of operator

#include<stdio.h>
int main() {
	int x=10;
	printf("Value of x=%d\n",x);
 	printf("Address of x=%d\n",&x);
 	printf("Address of x=%u\n",&x);
 	printf("Address of x=%p\n",&x);
	return 0;
} 

Output

Value of x=10
Address of x=37814068
Address of x=37814068
Address of x=0240FF34

What is the pointer

Pointer is a special variable which is used to store the address of another variable or any memory location.

int x=10;
int *p;
p=&x;
*p=20;
printf("x=%d",x);//x=20

  1. n the above program snippet p is a variable want to store the address of x. so p is declared as a pointer variable.
  2. The difference between the simple variable and pointer variable is that before the pointer declaration (*) is used and a simple variable can't hold the address whereas a pointer is able to hold the address.
  3. The statement int x; can be read as x is an integer variable. same as int* p can be read p is an integer pointer. The above-given statement can also be written as int *p.
  4. Once a variable holds the address of any variable(memory location) then it can manipulate the memory. This fact is shown by the statement *p=20;
  5. * is an operator known as dereference operator/indirection/value at the operator. when a pointer is dereferenced it jumps to that memory location which address pointer holds and then whatever is done affect that variable's location or simply say variable. To clarify the fact read some given lines: *p=20 can be read as the value at p=20; Address at (address of x)=20 So it should be clear that if we put the value at the address of x then x gets changed. So in the above example, x gets changed and it is confirmed through the next printf() statement.
  6. Read the following program and its output for understanding the pointer facts.

Program: Ways to use the pointer

#include<stdio.h>
int main() {
	int x=10;
	int *p;
 	p=&x;
	printf("Address of x=%p\n",&x);
 	printf("Address of x=%p\n",p);
 	printf("Value of p=%p\n",p);
 	printf("Value of x=%d\n",x);
 	printf("Value of x=%d\n",*p);
 	printf("Value of x=%d\n",*&x);
 	return 0;	
} 

Output

Address of x=0240FF34
Address of x=0240FF34
Value of p=0240FF34
Value of x=10
Value of x=10
Value of x=10

Some other facts related to pointer

  1. We have learn that pointer is a special variable used to store the address of another variable. We also learn that address are always a positive int technically called unsigned int.Address can't be negative and can't be any floating point value.
  2. So as to store the integer value we need an integer variable, so to store the address integer variable is required?.The answer is no.Because the type of the pointer doesn't show that which type of value a pointer will have the type of the pointer which type of indicate that which type of variable going to point.
  3. The type of the pointer actually shows the power of the pointer. Actually integer pointer is able to access the 2 bytes if integer occupy 2 byte. same as float pointer able to access 4 byte of memory and char pointer is able to access 1 byte of memory.
  4. So conclusion is to point the int variable int pointer is required same as to point the float variable float pointer is require and same for other types. Means the type of the pointer is same as the type of the variable.
  5. Each pointer occupy 2 bytes on 16-bit compiler whereas 4 bytes on 32-bit compiler. The memory occupied by the pointer doesn't vary according to the type. The memory occupied by the pointer is equal to the integer on that platform.
  6. The fundamental use of a pointer in the call by reference. What is called by reference this is discussed in a few minutes.

Program: To swap two numbers

#include<stdio.h>
void swap(int *p1,int *p2) {
	int t;
 	t=*p1;
 	*p1=*p2;
 	*p2=t;
}
 
int main() {
 	int x,y;
 	printf("Enter any two numbers: ");
 	scanf("%d%d",&x,&y);
 	
 	swap(&x,&y);
 	
 	printf("x=%d y=%d",x,y);
 	return 0;	
}

Output

Enter any two numbers: 5 9
x=9 y=5

Program Description

  1. In the previous chapter we have already discuss this problem. But if you remember that we pass the value from the main() function to the swap() function and swap() function change in the copy(formal argument) and actual argument doesn't get changed.
  2. The solution comes with the pointer. In the above program we don't pass the copy of value we pass the copy of the address from main() function to swap() function and the copy of address gets collected in p1 and p2. so p1 and p2 are declared as (int*) integer pointer.
  3. Here we don't swap the copy of the address. we actually get the value by dereferencing the pointer and then swap the value so actual value gets changed.

Function limitation and their solutions

While creating a program using the function, the required input is supplied by passing the arguments. We have already discussed the argument can be passed by two ways while function call

  1. Call by Value
  2. Call by Reference
  1. In call by value the copy of the variable value is passed and if formal argument changed actual argument doesn't affect. The second limitation of the function is that a function can't return multiple values. So how to deal when function need to return multiple outputs is as given.
  2. suppose we want to create a function sumavg() to calculate the sum and average of two numbers both the resulting sum and avg should be returned to the caller. The sample function definition is given below
    sumavg (int x,int y) { 
         return x+y; 
         return (x+y)/2.0; 
    }
    
    
  3. The problem with the above given code is that a function return the value immediately when return statement appears so the second return statement never executes. so multiple values can't be returned.
  4. The possible solution of given problem is that suppose a function can return multiple value and if value is successfully returned in main() function then collected in some variables. suppose in the above problem the result of sum gets collected in sum variable and average gets collected in avg variable.But unfortunately this is not possible.
  5. Now think, that if sum and avg collect the result in main() function but function can't return multiple values so this solution is failed but can we able to change the value of the variable available in main() through sumavg() function. Yes, this is possible. The following program is given based on the discussed fact.

Program: Find the sum and average of two numbers using single function sumavg()

#include<stdio.h>
void sumavg(int,int,int*,float*);
int main() {
	int x,y;
	int sum;
 	float avg;
 	
 	printf("Enter any two numbers: ");
 	scanf("%d%d",&x,&y);
 
	sumavg(x,y,&sum,&avg);
 
 	printf("Sum=%d\nAvg=%.2f",sum,avg);
 	
 	return 0;	
 }
 
void sumavg(int x,int y,int *p1,float *p2) {
 	*p1=x+y;
 	*p2=(x+y)/2.0f;
}

Output

Enter any two numbers: 4 7
Sum=11
Avg=5.50

Pointer to Pointer

Till now we have seen that the pointer can store the address of another variable. But pointer itself is a variable and occupy memory space so pointer also has an address. So now the question is that another pointer can store the address of pointer also. The answer is yes, but the pointer should be a pointer to a pointer. The fact is given in the following snippet.

int a=5;
int* p1;
int** p2;
p1=&a;
p2=&p1;
*p1=10;
printf("%d",a);//10
**p2=20;
printf("%d",a)//20

In the above program snippet p1 store the address of an integer so p1 is declared as int*(integer pointer). whereas p2 store the address of p1, so p2 should be a pointer to an integer pointer that is declared as int**.Sometime int** can be read as integer double pointer.

To access the value of a through p1 we have to dereference the p1 but to access the value of a through p2 we have to dereference p2 twice because once p2 is dereferenced it jumps to the p1 which holds the &a (address of a) so to access the value of a we need to again dereference it. The fact can be understood by the figure as given below.

pointer to pointer memory map

The uses of the pointer to pointer are discussed in next few chapter. In c their can be any level of pointer dereference is possible but as it increase the program becomes more complex and difficult to handle.

Comments

Popular posts from this blog

String in golang

Inline V/S Block Level Element

Floating point Data types in Go lang

Escape Sequence | Formatted Printing | Interview Questions

Program to check a year is leap year or not.

Printing in C programming

Arrays in C Language

Operators in C Language| Part-4

Sum of two numbers

Data types in Java