Lesson No 15 Pointers, Strings and Arrays
Lesson No 15 Pointers, Strings and Arrays
LESSON NO 15
Pointers, Strings and Arrays
Introduction
In the previous lecture, we had just started the discussion on the topic of pointers. This topic is little
complicated, yet the power we get with the pointers is very interesting. We can do many interesting things with
pointers. When other languages like Java evolve with the passage of time, pointers are explicitly excluded. In
today’s lecture, we will discuss pointers, the relationship between pointers and arrays, pointer expressions,
arithmetic with pointers, relationship between arrays and pointer, strings etc.
Pointer Expressions
and Arithmetic
Suppose we have an array y and yptr, a pointer to array. We can manipulate arrays with both y and yptr. To
access the fourth element of the array using y, we can say y[3]; with yptr, we can write as *(yptr + 4). Now we
have to see what happens when we increment or add something to a pointer. We know that y is a constant
pointer and it can not be incremented. We can write y[0], y[1] etc. On the other hand, yptr is a pointer variable
and can be written as the statement yptr = y. It means that yptr contains the address of the first element of the
array. However, when we say yptr++, the value of yptr is incremented. But how much? To explain it further, we
increment a normal integer variable like x++. If x contains 10, it will be incremented by 1 and become 11. The
increment of a pointer depends on its data type. The data type, the pointer points to, determines the amount of
increment. In this case, yptr is an integer pointer. Therefore, when we increment the yptr, it points to the next
integer in the memory. If an integer occupies four bytes in the memory, then the yptr++; will increment its value by
four.
This can be understood from the following example.
/* This program will print the memory address of a pointer and its incremented address. */
#include<iostream.h>
main()
{
int y[10]; /* an array of 10 integers */
int *yptr; /* an integer pointer */
yptr = y; /* assigning the start of array address to pointer */
// printing the memory address
cout << “The memory address of yptr = “ << yptr << endl ;
yptr++; /* incrementing the pointer */
// printing the incremented memory address
cout << “The memory address after incrementing yptr = ” << yptr << endl;
}
In the above program, the statement cout << yptr will show the memory address the yptr points to. You
will notice the difference between the two printed addresses. By default, the memory address is printed in
hexadecimal by the C output system. Therefore, the printed address will be in hexadecimal notation. The
difference between the two addresses will be four as integer occupies four bytes and yptr is a pointer to an
integer.
“When a pointer is incremented, it actually jumps the number of memory spaces according to the data
type that it points to”
The sample out put of the program is:
yptr which was pointing to the start of the array y, starts pointing to the next integer in memory after
incrementing it. In other words, yptr is pointing to the 2nd element of the array. On being incremented again,
the yptr will be pointing to the next element of the array i.e. y[2], and so on. We know that & is address operator
which can be used to get the memory address. Therefore, we can also get the address of the first element of the
array in yptr as:
yptr = &y[0] ;
y[0] is a single element and its address can be got with the use of. the address operator (&). Similarly we can
get the address of 2nd or 3rd element as &y[1], &y[2] respectfully. We can get the address of any array element and
assign it to yptr.
Suppose the yptr is pointing to the first element of the array y. What will happen if we increment it too much?
Say, the array size is 10. Can we increment the yptr up to 12 times? And what will happen? Obviously, we can
increment it up to 12 times. In this case, yptr will be pointing to some memory location containing garbage (i.e.
there may be some value but is useless for us). To display the contents where the yptr is pointing we can
use cout with dereference pointer as:
cout << *yptr ;
The above statement will display the contents where yptr is pointing. If the yptr is pointing to the first
element of the array, cout << *yptr will display the contents of the first element of the array (i.e. y[0]).
While incrementing the yptr as yptr ++, the statement cout << * yptr will display the contents of the
2nd element of the array(i.e. y[1]) and so on.
Here is an example describing different methods to access array elements.
In the above example, there are two new expressions i.e. *(yptr+5) and yptr[5]. In the statement *(yptr+5), yptr is
incremented first by 5 (parenthesis are must here). Resultantly, it points to the 6th element of the array. The
dereference pointer gives the value at that address. As yptr is a pointer to an integer, so it can be used as array
name. So the expression yptr[5] gives us the 6th element of the array.
The following example can explain how we can step through an entire array using pointer.
/* This program steps through an array using pointer */
#include <iostream.h>
main ()
{
int y[10] = {10,20,30,40,50,60,70,80,90,100};
int *yptr, i;
yptr = y; // Assigning the address of first element of array.
for (i = 0; i < 10 ; i ++)
{
cout << “\n The value of the element at position ” << i << “ is “ << *yptr;
yptr ++ ;
}
}
The output of the program is:
/* Program using pointer arithmetic */
Consider another example to elaborate #include <iostream.h>
the pointer arithmetic. main()
{
int x =10;
int *yptr;
yptr = &x;
cout << “The address yptr points to = ” << yptr << endl ;
cout << “The contents yptr points to = ” << *yptr << endl;
(*yptr) ++;
cout << “After increment, the contents are ” << *yptr << endl;
cout << “The value of x is = ” << x << endl;
}
“When a pointer is used to hold the memory address of a simple variable, do not increment or decrement the pointer.
When a pointer is used to hold the address of an array, it makes sense to increment or decrement the pointer “
Be careful while using pointers, as no warning will be given, in case of any problem. As pointers can point at any
memory location, so one can easily get the computers crashed by using pointers.
Remember that incrementing the pointer and incrementing the value where the pointer points to are two different
things. When we want to increment the pointer, to make it point to next element in the memory, we write as (yptr+
+); Use parenthesis when incrementing the address. If we want to increment the value where the pointer points to, it
can be written as (*yptr) ++; Keep in mind the precedence of operator. Write a program to test this.
The decrement of the pointer is also the same. yptr --; yptr -= 3 ; will decrement the yptr. Whereas the statement
(*yptr) --; will decrement the value where the yptr is pointing. So if the yptr is pointing to x the value of x will be
decremented by 1.
Pointers are associated to some data type as pointer to integer, pointer to float and pointer to char etc. When
a pointer is incremented or decremented, it changes the address by the number of bytes occupied by the data type
that the pointer points to. For example, if we have a pointer to an integer, by incrementing the pointer the address
will be incremented by four bytes, provided the integer occupies four bytes on that machine. If it is a pointer to float
and float occupies eight bytes, then by incrementing this pointer, its address will be incremented by eight bytes.
Similarly, in case of a pointer to a char, which normally takes one byte, incrementing a pointer to char will change
the address by one. If we move to some other architecture like Macintosh, write a simple program to check how
many bytes integer, float or char is taking with the use of simple pointer arithmetic. In the modern operating
systems like windows XP, windows 2000, calculator is provided under tools menu. Under the view option, select
scientific view. Here we can do hexadecimal calculations. So we can key in the addresses our programs are
displaying on the screen and by subtracting, we can see the difference between the two addresses. Try to write
different programs and experiment with these.
We have seen that we can do different arithmetic operations with pointers. Let's see can two pointers be
added? Suppose we have two pointers yptr1 and yptr2 to integer and written as yptr1 + yptr2 ; The compiler will
show an error in this statement. Think logically what we can obtain by adding the two memory addresses.
Therefore, normally compiler will not allow this operation. Can we subtract the pointers? Yes, we can. Suppose we
have two pointers pointing to the same memory address. When we subtract these, the answer will be zero.
Similarly, if a pointer is pointing to the first element of an integer array while another pointer pointing to the second
element of the array. We can subtract the first pointer from second one. Here the answer will be one, i.e. how many
array elements are these two pointers apart.
Consider the following sample program:
This diagram shows how an array occupies space in the memory. Suppose, we have an integer array
named y and yptr is a pointer to an integer and is assigned the address of the first element of the array. As this is
an integer array, so the difference between each element of the array is of four bytes. When the yptr is
incremented, it starts pointing to the next element in the array.
Pointer Comparison Consider a sample program as follows:
We have seen pointers in different expressions and arithmetic /* Program using the dereference pointer comparison */
#include <iostream.h>
operations. Can we compare pointers? Yes, two pointers can be main ()
compared. Pointers can be used in conditional statements as usual {
variables. All the comparison operators can be used with pointers i.e. int x, y, *xptr, *yptr;
cout << “ \n Please enter the value of x = “ ;
less than, greater than, equal to, etc. Suppose in sorting an array we
cin >> x ;
are using two pointers. To test which pointer is at higher address, we cout << “ \n Please enter the value of y = “;
can compare them and take decision depending on the result. cin >> y ;
Again consider the two pointers to integer i.e. yptr1 and yptr2. Can we xptr = &x;
yptr = &y;
compare *yptr1 and *yptr2? Obviously *yptr1 and *yptr2 are simple if (*xptr > *yptr )
values. It is the value of integer yptr1, yptr2 points to. When we say {
*yptr1 > *yptr2, this is a comparison of simple two integer values. cout << “ \n x is greater than y “;
}
Whenever we are using the dereference pointer (pointers with *), all
else
normal arithmetic and manipulation is valid. Whenever we are using {
pointers themselves, then certain type of operations are allowed and cout << “\n y is greater than x “;
restrictions on other. Make a list what can we do with a pointer and }
}
what we cannot.
Exercise:
Print out the address and the value of a character pointer pointing to some character.
Write a function which copies an array of integers from one array to other
TIPS
While incrementing the pointers, use the parenthesis