{
int i=500;
printf (“address of i = %u”, &i);
printf (“Value of i = %d”, i);
}
Indirection operator, * is also called value at address operator. Its operand is the address of a memory location and it returns the value stored at that address. It works only on pointer variables.
e.g.:-
main()
{
int i=500;
printf (“Address of i = %u”, &i);
printf (“\n Value of i = %d”, i);
printf (“\n Value of i = %d”, *(&i) );
}
will return, Address of i = 65496
Value of i = 500
Value of i = 500
The value of *(&i) is the same as value of i. *(&i) means the value stored at the address of i, 500.
Declaring Pointer Variables
Pointers are declared using the indirection operator, *.
syntax : type *pointer-name;
Where type is any valid C data-type and pointer-name is a pointer variable. The declaration tells the compiler that pointer-name is a variable used to store the address of a value, of the given type. But pointer-name is of type pointer.
e.g.:- int *j;
This declaration tells the compiler that j will be used to store the address of an integer value. i.e., j points to an integer, or *j will return a value of type int. j is not of type integer but it is a pointer to an integer value.
e.g.:- char *ch; float *s;
The declaration float *s does not mean that s is going to contain a floating-point value. The meaning is, s is going to contain the address of a floating-point value. Similarly char *ch means that ch is going to contain the address of a character variable or the value at address stored in ch is going to be a char.
Assigning Values to Pointers
Values can be assigned to pointer variables through the reference operators and the assignment statement.
Syntax: pointer-name = &variable-name;
e.g.:- int i = 500;
int *j;
j = &i;
i
|
|
j
|
500
|
|
65496
|
65496
|
|
65498
|
Since j is also a variable it’s address also can be printed using prefixing j with the & operator. i.e., &j. The addresses are always whole numbers and it should be printed using the %u conversion character.
e.g.:-
main()
{
int i = 500;
int *j;
j = &i;
printf (“Address of i = %u”, &i);
printf (“\n Address of i = %u”, j);
printf (“\n Address of j = %u”, &j);
printf (“\n Value of j = %u”, j);
printf (“\n Value of i = %d”, i);
printf (“\n Value of i = %d”, *(&i) );
printf (“\n Value of i = %d”, *j);
printf (“\n Value of j = %u”, *(j));
printf (“\n Value of i = %d”, *(*(&j)));
}
Multiple Indirection
It is possible to have a pointer point to another pointer that points to the target value. This situation is called multiple indirection, pointer to pointer. In the case of pointer to a pointer, the first pointer contains the address of the second pointer, which points to the variable that contains the value.
Variable
|
|
Pointer
|
|
Pointer-to-pointer
|
I
|
|
j
|
|
k
|
500
|
|
65496
|
|
65498
|
65496
|
|
65498
|
|
65500
|
A variable that is a pointer to pointer can be declared by placing an additional asterisk in the front of the variable name.
e.g.:- int **k;
This tells that k is a pointer-to-pointer of type int. To access the target values indirectly apply the indirection operator twice.
e.g.:-
main()
{
int i = 500;
int *j, **k;
j = &i;
k = &j;
printf (“Address of i = %u”, &i);
printf (“\n Address of i = %u”, j);
printf (“\n Address of i = %u”, *k);
printf (“\n Address of j = %u”, &j);
printf (“\n Address of j = %u”, k);
printf (“\n Address of k = %u”, &k);
printf (“\n Value of j = %u”, j);
printf (“\n Value of k = %u”, k);
printf (“\n Value of i = %d”, i);
printf (“\n Value of i = %d”, *(&i) );
printf (“\n Value of i = %d”, *j);
printf (“\n Value of i = %u”, **k);
}
Call by value and Call by reference
Functions communicate with each other by passing arguments. Arguments can generally be passed to functions in one of the two ways.
Sending the values of the arguments (Call by value)
Sending the addresses of the arguments (Call by Reference)
When the arguments of a function are passed by value, a copy of the value contained in the actual arguments is sent from the calling routine to the formal arguments of the called function, rather than allowing the function direct access to the memory location of the variables. So in Call by value the function uses a copy of the actual arguments only. It cannot access the actual memory location of the variable and therefore cannot change the value of the actual argument of the calling function. Using this method, variables can be localised from within the functions.
e.g.:-
# include
void swap(int x, int y);
main()
{
int i = 10, j = 20;
clrscr();
printf(“Before Swapping”);
printf(“\n i = %d and j = %d”, i, j);
swap(i, j);
printf(“\n i = %d and j = %d”, i, j);
}
void swap(int x, int y)
{
int t;
t = y;
y = x;
x = t;
}
In Call by Reference the function is allowed access to the actual memory location of the actual arguments of the calling routine. i.e., The address of actual arguments are copied into formal arguments of the called function. Therefore changes made to the formal arguments in the called function will change the values of the actual arguments in the calling function.
e.g.:-
# include
void swap(int *x, int *y);
main()
{
int i = 10, j = 20;
clrscr();
printf(“Before Swapping”);
printf(“\n i = %d and j = %d”, i, j);
swap(&i, &j);
printf(“\n i = %d and j = %d”, i, j);
}
void swap(int *x, int *y)
{
int t;
t = *y;
*y = *x;
*x = t;
}
Pointer Arithmetic
–, ++, – –, * and & are all unary operators having the same precedence of evaluation. When several of these unary operators appear in an expression, the evaluation takes place from right to left.
e.g.:-
int i = 500;
int *ptr;
ptr = &i;
++ ptr or ptr++
|
Points to the next integer after i.
|
– –ptr or ptr– –
|
Points to the integer previous to i.
|
ptr + j
|
Points to the jth integer after i.
|
ptr – j
|
Points the jth integer before i.
|
++*ptr or (*ptr)++
|
Will increment i by 1(one).
|
*++ptr
|
Will fetch the value of the next integer after i.
|
*ptr++
|
Will print the contents of i and increments the ptr by 1(one) which will point to the next integer after i.
|
Pointer Comparison
Comparison between the two pointer variables is possible if they both point to variables of the same type. Consider ptra and ptrb that point to data elements a and b respectively of same type. Then,
ptra < ptrb
|
Returns true, if a is stored before b in memory
|
ptra > ptrb
|
Returns true, if a is stored after b
|
ptra <= ptrb
|
Returns true, if a is stored before b or ptra and ptrb both are point to the same location
|
ptra >= ptrb
|
Returns true, if a is stored after b or ptra and ptrb both are point to the same location
|
ptra = = ptrb
|
Returns true, if both pointers are point to the same location
|
ptra != ptrb
|
Returns true, if both pointers point to the different data elements but of same type
|
ptra = = null
|
Returns true if ptra is assigned NULL
|
Passing Pointers (Addresses) to Functions
When a pointer is passed to a function as argument address of a data item is passed to the function making it possible to access the contents of that address from within the function. This method enables a two-way transfer of data between the calling routine and the called function.
Formal arguments of a function which are pointers are preceded by an asterisk (*) indicating them to be pointers. Function declarations (prototypes) containing pointers must also contain an asterisk (*). Actual pointer arguments in a function call must either be declared pointers or referenced variables. (e.g.:- &var)
e.g.:-
main()
{
int i, *ptr, j;
ptr = &i;
............
function(ptr, &j);
............
}
function(int *i, int *j)
{
..........
return;
}
Pointers and Arrays
The name of an array written without the indices is a pointer-constant, which points to the beginning, (zeroth element) of the array. The array name is a pointer whose value is fixed by the compiler, depending on where the array is stored in memory. The value of pointer constant cannot be changed in the program. But this value can be assigned to a pointer variable.
e.g.:-
int num[12], *ptr;
ptr = num;
OR
ptr = &num[0];
Here the array name num, which is a pointer-constant, is assigned to the pointer variable ptr. Both the array name num and ptr point to the first element of array.
|
ptr
|
|
|
|
|
|
|
num
|
|
|
|
- - - - - - - - - - -
|
|
|
|
&num[0]
|
|
|
|
|
&num[10]
|
&num[11]
|
e.g.:-
main()
{
int num[10], *ptr, *pa;
ptr = num;
pa = &num[0];
printf(“The array starts at “);
printf(“\n %u ------%u”, ptr, pa);
getch();
}
Q1) Write a program to print the numbers stored in an array using pointers (i.e., without array subscripting)
main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10}, *ptr = arr, i;
for(i=0; i<10; i++)
{
printf(“%d \n”, *ptr++);
}
getch();
}
Q2) Add 10 to each elements in an array of integers
main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10}, *ptr = arr, i;
for(i=0; i<10; i++)
{
*ptr++ += 10;
printf(“%d \n”, *(arr+i));
}
getch();
}
Q3) Display the contents array using pointers & functions
main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10}, i;
for(i=0; i<10; i++)
{
print(&arr[i]);
}
getch();
}
print(int *n)
{
printf(“%d \n”, *n);
}
Q4) Display the contents of array using functions & pointers
main() print(int *n)
{ {
int arr[10] = {1,2,3,4,5,6,7,8,9,10}, i; show(&n);
for(i=0; i<10; i++) }
{ show(int **y)
print(&arr[i]); {
} printf(“%d \n”, **y);
getch(); }
}
Passing Arrays to Functions (Using Pointers)
In order to pass an entire array to a function mention the address of the first element (with subscript 0) of that array as the actual argument (The address of the element with subscript zero is also called the base address. Also you can mention the name of the array instead of the address of first element, because the array name is a pointer-constant that contains the address of the fist element of that array.
The formal argument in the function header of the called function must be a pointer variable to accept the address.
e.g.(1) e.g.:- (2)
main() main()
{ {
int arr[3] = {1,2,3}; int arr[3] = {1,2,3};
disp(arr); disp(&arr[0]);
} }
disp(int *arr) disp(int *arr)
{ {
int i; int i;
for(i=0; i<3; i++) for(i=0; i<3; i++)
{ {
printf(“%d \n”, *arr); printf(“%d \n”, *arr);
arr++; arr++;
} }
getch(); getch();
} }
e.g.(3)
main()
{
char name[] = “Ajith”;
print(name);
}
print(char *name) print(char *name)
{ {
printf(“%s \n”, name); int i;
for( ; *name != NULL; name++) printf(“%s \n”, name);
{ for(i=0;*(name + i); i++)
printf(“%c \n”, *name); {
} printf(“%c \n”, *(name + i));
getch(); }
} getch();
Share with your friends: |