Pointer:
POINTERS
A variable in a program is something with a name, the value of which can vary. The way the
compiler and linker handles this is that it assigns a specific block of memory within the computer
to hold the value of that variable. The size of that block depends on the range over which the
variable is allowed to vary. For example, on 32 bits PC's the size of an integer variable is 4 bytes.
On older 16 bits PCs integers were 2 bytes. In C (programming language), the size of a variable
type such as an integer need not be the same on all types of machines. Furthermore, there are more
than one type of integer variable in C, which are integers, long integers and short integers. This
document assumes the use of a 32 bits system with 4 byte integers.
If you want to know the size of the various types of integers on your system, running the following
code will give you that information.
//Program to find the sum of six numbers with arrays and pointers.
#include <stdio.h>
int main( ){
int i, class[6],sum=0;
printf("Enter 6 numbers:\n");
for(i=0;i<6;++i){
scanf("%d",(class+i)); // (class+i) is equivalent to &class[i]
printf("\n index address=%x",(class+i));
sum += *(class+i); // *(class+i) is equivalent to class[i]
}
printf("\nSum=%d",sum);
return 0;
}
#include <stdio.h>
int main()
{
printf("size of a short is:%d bytes\n", sizeof(short));
printf("size of a int is :%d bytes\n", sizeof(int));
printf("size of a long is :%d byts\n", sizeof(long));
return 0;
}
Output will be:
size of a short is: 2 bytes
size of a int is : 4 bytes
size of a long is : 4 bytes
When we declare a variable we inform the compiler of two things, the name of the variable and
the type of the variable. For example, we declare a variable of type integer with the name k by
writing:
int k;
On observing the "int" part of this statement the compiler sets aside 4 bytes of memory (on a PC)
to hold the value of the integer. It also sets up a symbol table. In that table it adds the symbol k
and the relative address in memory where those 4 bytes were set aside.
Thus, later if we write:
k = 2;
We expect that, at run time when this statement is executed, the value 2 will be placed in that
memory location reserved for the storage of the value of k. In C, we refer to a variable such as the
integer k as an "object".
In a sense there are two "values" associated with the object k. One is the value of the integer stored
there (2 in the above example) and the other the "value" of the memory location, i.e., the address
of k. Some texts refer to these two values with the nomenclature r-value (right value, pronounced
"are value") and l-value (left value, pronounced "el value") respectively.
In some languages, the l-value is the value permitted on the left side of the assignment operator '='
(i.e. the address where the result of evaluation of the right side ends up). The r-value is that which
is on the right side of the assignment statement, the 2 above. R-values cannot be used on the left
side of the assignment statement. Thus: 2 = k; is illegal. "An object is a named region of storage;
an l-value is an expression referring to an object."
Ok, now consider:
int j, k;
r-value
k = 2;
l-value (address of k)
j = 7; <-- line 1
l-value (address of j)
l-value (address of k)
k = j; <-- line 2
r-value (value of j i.e. 7)
In the above, the compiler interprets the j in line 1 as the address of the variable j (its l-value) and
creates code to copy the value 7 to that address. In line 2, however, the j is interpreted as its r-
value (since it is on the right hand side of the assignment operator '='). That is, here the j refers to
the value stored at the memory location set aside for j, in this case 7. So, the 7 is copied to the
address designated by the l-value of k.
In all of these examples, we are using 4 byte integers so all copying of r-values from one storage
location to the other is done by copying 4 bytes. Had we been using two byte integers, we would
be copying 2 bytes.
Pointer variables:
Now, let's say that we have a reason for wanting a variable designed to hold an l-value (an address).
Such a variable is called a pointer variable. Pointer is a derived data type in C. It is built from one
of the fundamental data type available in C. Pointer contains memory address as their values. Since
memory addresses are the locations in the computer memory where program instructions and data
are stored, pointers can be used to access and manipulate data stored in the memory. In C, when
we define a pointer variable we do so by preceding its name with an asterisk (*). In C we also give
our pointer a type which, in this case, refers to the type of data stored at the address we will be
storing in our pointer.
For example, consider the variable declaration:
int *ptr;
ptr is the name of variable. But, back to using our new variable ptr. Suppose now that we want to
store in ptr the address of our integer variable k. To do this we use the unary & operator and write:
ptr = &k;
What the & operator does is retrieve the l-value (address) of k, even though k is on the right hand
side of the assignment operator '=', and copies that to the contents of our pointer ptr. Now, ptr is
said to "point to" k. Bear with us now, there is only one more operator we need to discuss.
The "dereferencing operator" is the asterisk and it is used as follows:
*ptr = 7;
will copy 7 to the address pointed to by ptr(i.e the address of k). Thus if ptr "points to" (contains
the address of) k, the above statement will set the value of k to 7. That is, when we use the '*' this
way we are referring to the value of that which ptr is pointing to, not the value of the pointer itself.
For example by using a C Programs:
#include<stdio.h>
void main()
{
int *ptr,k;
k=10;
printf("The address of K=%x\n",&k);
printf("The value of K=%d\n",k);
ptr=&k;
*ptr=7;
printf("The value of K=%d\n",k);
printf("The value of Ptr=%d\n",*ptr);
}
Output: The address of K=12ff40
The value of K=10
The value of K=7
The value of Ptr=7
Pointer VS One dimensional Array:
C Program for adding five numbers using one dimension array:
#include<stdio.h>
void main()
{
int sum,a[5],i;
sum=0;
for(i=0;i<5;++i)
{
printf("Enter the input value%d:",i+1);
scanf("%d",&a[i]);
sum=sum+a[i];
}
printf("Value of sum:%d\n",sum);
}
Used memory size: int a[5] + int sum
= 5*2+2
=12 bytes
C program for adding five numbers using pointer variable:
How does the free #include<stdio.h>
command work in C? #include<stdlib.h>
void main(){
free in C is used to de- int *a, sum,i;
allocate or free up the
a=(int*)malloc(5*sizeof(int));
space allocated by the
functions like malloc(). sum=0;
free(ptr); takes only one for(i=0;i<5;++i){
argument, i.e., the printf("Enter the number %d:",i+1);
pointer pointing to the scanf("%d",(a+i));
memory location to be sum=sum + *(a+i);
de-allocated. free()
function in C doesn't
}
return any value. It has printf("\nThe value of sum:%d\n",sum);
a return type of void. free(a);
}
Used memory size: 5*sizeof(int)+int sum
=5*2+2 bytes
=12 bytes
But allocated memory for pointer variable ‘a’ can be released after execution the program by using free( ) function.
That means 5*2=10 bytes will be free. So, finally only 2 bytes are allocated for sum integer variable. Its good practice
for memory saving.
Necessity of Pointers
If you like to exchange two values, how does it possible? Without pointer variable is it possible? Or with pointer
variable is it possible? You might get your answer by observing the following two programs (without pointer variables
and with pointer variables).
Swap Program: Without pointer
#include<stdio.h>
#include<stdlib.h>
void swap(int x,int y);
void main(){
int b,d;
b=10;
d=12;
printf("Before swap:%d %d",b,d);
swap(b,d);
printf("\nAfter calling swap( b,d):%d %d\n",b,d);
}
void swap(int x, int y){
int temp=x;
x=y;
y=temp;
}
Output: Before swap: 10 12
After calling swap ( b,d): 10 12
But the result does not show the swapped output.
With pointer:
#include<stdio.h>
#include<stdlib.h>
void swap(int *x,int *y);
void main()
{
int b,d;
b=10;
d=20;
printf("Before swap:%d %d",b,d);
swap(&b,&d);
printf("\nAfter calling swap(b,d):%d %d\n",b,d);
}
void swap(int *x,int *y)
{
int temp=*x;
*x=*y;
*y=temp;
}
Output: Before swap: 10 20
After calling swap(b,d) : 20 10
The result shows the swapped output.