Lab Sheet 8
Lab Sheet 8
CONCEPT OF POINTERS
Different from other normal variables which can store values, pointers are
special variables that can hold the address of a variable. Since they store
memory address of a variable, the pointers are very commonly said to point to
variables. Lets try to understand the concept.
A pointer variable has its own address 2047 but stores 1001, which is
the address of the variable var
2.
OR
<pointer declaration>
<name-of-pointer> = <address of a variable>
Note that the type of variable above should be same as the pointer type.(Though
this is not a strict rule but for beginners this should be kept in mind).
For example :
char ch = 'c';
OR
char ch = 'c';
char *chptr;
chptr = &ch //initialize
In the code above, we declared a character variable ch which stores the value
c. Now, we declared a character pointer chptr and initialized it with the
address of variable ch.
Note that the & operator is used to access the address of any type of variable.
How to Use a Pointer?
A pointer can be used in two contexts.
Context 1: For accessing the address of the variable whose memory address the
pointer stores.
Again consider the following code :
char ch = 'c';
char *chptr = &ch;
Now, whenever we refer the name chptr in the code after the above two lines,
then compiler would try to fetch the value contained by this pointer variable,
which is the address of the variable (ch) to which the pointer points. i.e. the
value given by chptr would be equal to &ch.
For example :
char *ptr = chptr;
The value held by chptr (which in this case is the address of the variable ch)
is assigned to the new pointer ptr.
Context 2: For accessing the value of the variable whose memory address the
pointer stores.
Continuing with the piece of code used above :
char ch = 'c';
char t;
char *chptr = &ch;
t = *chptr;
We see that in the last line above, we have used * before the name of the
pointer. What does this asterisk operator do?
Well, this operator when applied to a pointer variable name(like in the last line
above) yields the value of the variable to which this pointer points. Which
means, in this case *chptr would yield the value kept at address held by chptr.
Since chptr holds the address of variable ch and value of ch is c, so
*chptr yeilds c.
When used with pointers, the asterisk * operator is also known as value of
operator.
POINTER ARITHMETIC
Pointers do not have to point to single variables. They can also point at the cells
of an array. For example, we can write
int *ip;
int a[10];
ip = &a[3];
and we would end up with ip pointing at the fourth cell of the
array a (remember, arrays are 0-based, so a[0] is the first cell). We could
illustrate the situation like this:
We'd use this ip just like the one in the previous section: *ip gives us
what ip points to, which in this case will be the value in a[3].
Once we have a pointer pointing into an array, we can start doing pointer
arithmetic. Given that ip is a pointer to a[3], we can add 1 to ip:
ip + 1
What does it mean to add one to a pointer? In C, it gives a pointer to the cell one
farther on, which in this case is a[4]. To make this clear, let's assign this new
pointer to another pointer variable:
ip2 = ip + 1;
Now the picture looks like this:
If we now do
*ip2 = 4;
we've set a[4] to 4. But it's not necessary to assign a new pointer value to a
pointer variable in order to use it; we could also compute a new pointer value
and use it immediately:
*(ip + 1) = 5;
In this last example, we've changed a[4] again, setting it to 5. The parentheses
are needed because the unary ``contents of'' operator * has
higher precedence (i.e., binds more tightly than) the addition operator. If we
wrote *ip + 1, without the parentheses, we'd be fetching the value pointed to
by ip, and adding 1 to that value. The expression *(ip + 1), on the other hand,
accesses the value one past the one pointed to by ip.
Given that we can add 1 to a pointer, it's not surprising that we can add and
subtract other numbers as well. If ip still points to a[3], then
*(ip + 3) = 7;
sets a[6] to 7, and
*(ip - 2) = 4;
sets a[1] to 4.
Up above, we added 1 to ip and assigned the new pointer to ip2, but there's no
reason we can't add one to a pointer, and change the same pointer:
ip = ip + 1;
Now ip points one past where it used to (to a[4], if we hadn't changed it in the
meantime). The shortcuts we learned in a previous chapter all work for pointers,
too: we could also increment a pointer using
ip += 1;
or
ip++;
Of course, pointers are not limited to ints. It's quite common to use pointers to
other types, especially char. Here is the innards of the mystrcmp function we
saw in a previous chapter, rewritten to use pointers. (mystrcmp, you may recall,
compares two strings, character by character.)
char *p1 = &str1[0], *p2 = &str2[0];
while(1)
{
if(*p1 != *p2)
return *p1 - *p2;
if(*p1 == '\0' || *p2 == '\0')
return 0;
p1++;
p2++;
}
The autoincrement operator ++ (like its companion, --) makes it easy to do two
things at once. We've seen idioms like a[i++] which accesses a[i] and
simultaneously increments i, leaving it referencing the next cell of the array a.
We can do the same thing with pointers: an expression like *ip++ lets us access
what ip points to, while simultaneously incrementing ip so that it points to the
next element. The preincrement form works, too: *++ip increments ip, then
accesses what it points to. Similarly, we can use notations like *ip-- and *--ip.
Q. What would be the equivalent pointer expression for referring the array
element a[i][j][k][l]
A.
((((a+i)+j)+k)+l)
B.
*(*(*(*(a+i)+j)+k)+l)
C.
(((a+i)+j)+k+l)
D.
((a+i)+j+k+l)
Answer: Option B
#include <stdio.h>
void swap(int *a,int *b);
int main(){
int num1=5,num2=10;
swap(&num1,&num2); /* address of num1 and num2 is passed to swap
function */
printf("Number1 = %d\n",num1);
printf("Number2 = %d",num2);
return 0;
}
void swap(int *a,int *b){ /* pointer a and b points to address of num1 and
num2 respectively */
int temp;
temp=*a;
*a=*b;
*b=temp;
}
Output
Number1 = 10
Number2 = 5
Explanation
The address of memory location num1 and num2 are passed to function
and the pointers *a and *b accept those values. So, the
pointer a and b points to address of num1 and num2 respectively. When,
the value of pointer are changed, the value in memory location also
changed correspondingly. Hence, change made to *a and *b was reflected
in num1 and num2 in main function.
Questions:
1. consider the snippet of the swap:
void swap(int *a, int *b){ /* pointer a and b points to address of
num1 and num2 respectively */
int temp;
temp=*a;
a=b;
*b=temp;
}
2. consider the snippet of the swap:
void swap(int *a, int *b){ /* pointer a and b points to address of
num1 and num2 respectively */
*a ^= *b;
*a ^= *b;
*a ^= *b;
}
#include <stdio.h>
int main() {
int b=10;
return 0;
}
The output of this call by reference source code example will look like this:
function there is some before and after print statement done and there is 10
added to the value at the memory pointed by y. Therefore at the end of the
function the value is 20. Then in main() we again print the variable b and as
you can see the value is changed (as expected) to 20.
int arr[5]={ 1, 2, 3, 4, 5 };
Assuming that the base address of arr is 1000 and each integer requires two
byte, the five element will be stored as follows
Here variable arr will give the base address, which is a constant pointer pointing
to the element, arr[0]. Therefore arr is containing the address of arr[0] i.e 1000.
int *p;
p = arr;
or p = &arr[0]; //both the statements are equivalent.
Now we can access every element of array arr using p++ to move from one
element to another.
NOTE : You cannot decrement a pointer once incremented. p-- won't work.
Pointer to Array
As studied above, we can use a pointer to point to an Array, and then we can use
that pointer to access the array. Lets have an example,
int i;
int a[5] = {1, 2, 3, 4, 5};
int *p = a; // same as int*p = &a[0]
for (i=0; i<5; i++)
{
printf("%d", *p);
p++;
}
In the above program, the pointer *p will print all the values stored in the array
one by one. We can also use the Base address (a in above case) to act as pointer
and print all the values.
int main()
{
int array[3] = {45, 67, 89};
printf ("%p\n", array);
printf ("%p\n", & array);
printf ("%p\n", & array[0]);
return 0;
prints out
0xbfbfd924
0xbfbfd924
0xbfbfd924
printf("\n");
return 0;
}
void swap(char* src, char* dest)
{
*src ^= *dest;
*dest ^= *src;
*src ^= *dest;
}