0% found this document useful (0 votes)
20 views

Lesson No 15 Pointers, Strings and Arrays

This document discusses pointers, arrays, and strings in C programming. It explains that: 1) Array names are constant pointers that point to the first element of the array. Pointer variables can point to any memory location. 2) When a pointer is incremented, it moves to the next memory location based on the data type. For integer pointers, each increment is by the size of an integer (4 bytes). 3) Pointers allow accessing array elements using pointer arithmetic like *(ptr + index) or ptr[index]. Incrementing a pointer steps through the array elements.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views

Lesson No 15 Pointers, Strings and Arrays

This document discusses pointers, arrays, and strings in C programming. It explains that: 1) Array names are constant pointers that point to the first element of the array. Pointer variables can point to any memory location. 2) When a pointer is incremented, it moves to the next memory location based on the data type. For integer pointers, each increment is by the size of an integer (4 bytes). 3) Pointers allow accessing array elements using pointer arithmetic like *(ptr + index) or ptr[index]. Incrementing a pointer steps through the array elements.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 20

CS-201

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.

Relationship between Pointers and Arrays


When we write int x, it means that we have attached a symbolic name x, at some memory location. Now we
can use x = 10 which replaces the value at that memory location with 10. Similarly while talking about arrays,
suppose an array as int y[10]. This means that we have reserved memory spaces for ten integers and named it
collectively as y. Now we will see what actually y is? 'y' represents the memory address of the beginning of this
collective memory space. The first element of the array can be accessed as y[0]. Remember arrays index starts
from 0 in C language, so the memory address of first element i.e. y[0] is stored in y.
“The name of the array is a constant pointer which contains the memory address of the first element of the
array”
The difference between this and an ordinary pointer is that the array name is a constant pointer. It means
that the array name will always point to the start of the array. In other words, it always contains the memory
address of the first element of the array and cannot be reassigned any other address. Let's elaborate the point
with the help of following example.
  int y[10];
  int *yptr;
In the above statements, we declare an array y of ten integers and a pointer to an integer i.e. yptr. This pointer
may contain a memory address of an integer.
             yptr = y;
This is an assignment statement. The value of y i.e. the address of the first element of the array is
assigned to yptr. Now we have two things pointing to the same place, y and yptr. Both are pointing to the first
element of the array. However, y is a constant pointer and always points to the same location whereas yptr is a
pointer variable that can also point to any other memory address.

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.

/* This program shows different ways to access array elements */


 
#include <iostream.h>
 
main ()
{
int y[10] = {0,5,10,15,20,25,30,35,40,45};
int *yptr;
 
yptr = y;            /* Assigning the address of first element of array */
 
cout << “Accessing 6th element of array as y[5] = ” << y[5] << endl;
 
cout  <<  “Accessing 6th element of array as *(yptr + 5) = ” << *(yptr + 5) << endl; 
 
cout << “Accessing 6th element of array as yptr[5] = “ << yptr[5] << endl;
}
The output of the program is:

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;
}

The output of the program is:


Here the statement (*yptr) ++ is read as “increment whatever yptr points to”. This will increment the value of the
variable. As yptr and x both are pointing to the same location, the contents at that location becomes 11. Consider the
statement *yptr + 3 ; This is an expression and there is no assignment so the value of x will not be changed where as
the statement *yptr += 3; will increment the value of x by 3. If we want to increment the pointer and not the contents
where it points to, we can do this as yptr ++; Now where yptr is pointing? The yptr will be now pointing four bytes
away from the memory location of x. The memory location of x is a part of program, yet after incrementing yptr, it is
pointing to some memory area, which is not part of the program. Take this as an exercise. Print the value of yptr and
*yptr and see what is displayed? Be sure, it is not illegal and the compiler does not complain. The error will be
displayed if we try to write some value at that memory address.

“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:

/* Program using the pointer subtraction */


 
#include <iostream.h>
 
main ()
{
            int y[10], *yptr1, *yptr2;
 
            yptr1 = &y[0];
            yptr2 = &y[3];
 
            cout << “ The difference = “ << yptr2 - yptr1;
}

The output of the program is:


In the above program, we have taken two integer pointers yptr1 and yptr2 and an integer array y[10]. The
pointer yptr1 is pointing to the address of the first element of the array while yptr2 is pointing to the 4th element of the
array. The difference between these two pointers can be shown by using cout statement. Here the result should be
twelve. But the program will show the result as three. When we increment an integer pointer by 1, we have seen that
the address is changed by four. When we subtract pointers, it tells us the distance between the two elements that
the pointers pointed to. It will tell us how many array elements are between these two pointers. As the yptr1 is
pointing to y[0] and the yptr2 is pointing to y[3], so the answer is three. In a way, it tells how many units of data type
(pointers data type) are between the two pointers. Pointer addition is not allowed, however, pointer subtraction is
allowed as it gives the distance between the two pointers in units, which are the same as the data type of the
pointer. 
A memory image of an array with a pointer.

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.

The output of the program is:


Pointer, String and Arrays
We have four basic data types i.e. char, int, float and double. Character strings are arrays of
characters. Suppose, there is a word or name like Amir to store in one entity. We cannot store it into a char variable
because it can store only one character. For this purpose, a character array is used. We can write it as: 
             char name [20];
We have declared an array name of 20 characters .It can be initialized as: 
            name[0] = ‘A’ ;
            name[1] = ‘m’ ;
            name[2] = ‘i’ ;
            name[3] = ‘r’ ;
  Each array element is initialized with a single character enclosed in single quote. We cannot use more than one
character in single quotes, as it is a syntax error. Is the initialization of the array complete? No, the character
strings are always terminated by null character ‘\0’. Therefore, we have to put the null character in the end of the
array.
             name[4] = ‘\0’ ;
Here we are using two characters in single quotes. But it is a special case. Whenever back slash ( \ ) is used,
the compiler considers both the characters as single (also known as escape characters). So ‘\n’ is new line
character, ‘\t’ a tab character and ‘\0’ a null character. All of these are considered as single characters. What is the
benefit of having this null character at the end of the string? Write a program, do not use the null character in the
string and try to print the character array using cout and see what happens? cout uses the null character as the
string terminating point. So if cout does not find the null character it will keep on printing. Remember, if we want to
store fifteen characters in an array, the array size should be at least sixteen i.e. fifteen for the data and one for the
null character.
Do we always need to write the null character at the end of the char array by ourselves? Not always, there is a short
hand provided in C, i.e. while declaring we can initialize the arrays as:
             char name[20] = “Amir”;
When we use double quotes to initialize the character array, the compiler appends null character at the end of the
string.
“Arrays must be at least one character space larger than the number of printable characters which are to be stored”
Example:
Write a program which copies a character array into given array.
Solution:
Here is the complete code of the program:
/* This program copies a character array into a given array */
#include <iostream.h>
main( )
{
            char strA[80] = "A test string";
            char strB[80];
The output of the program is:
            char *ptrA;         /* a pointer to type character */
            char *ptrB;         /* another pointer to type character */
            ptrA = strA;       /* point ptrA at string A */
            ptrB = strB;       /* point ptrB at string B */
            while(*ptrA != '\0')          
            {
                        *ptrB++ = *ptrA++;         // copying character by character
            }           
            *ptrB = '\0';
            cout << “String in strA = ” << strA << endl;          /* show strA on screen
*/
            cout << “String in strB = ” << strB << endl;          /* show strB on screen
*/
Explanation:
Suppose, we have declared a char array named strA of size 80 and initialized it with some value say “A
test String” using the double quotes. Here we don’t need to put a null character. The compiler will automatically
insert it. But while declaring another array strB of the same size, we declare two char pointers *ptrA and *ptrB.
The objective of this exercise is to copy one array into another array. We have assigned the starting address of
array strA to ptrA and strB to ptrB. Now we have to run a loop to copy all the characters from one array to other.
To terminate the loop, we have to know about the actual number of characters or have to use the string
termination character. As we know, null character is used to terminate a string, so we are using the condition in
'while loop' as: *ptrA != ‘\0’ , simply checking that whatever ptrA is pointing to is not equal to ‘\0’. Look at the
statement *ptrB++ = *ptrA++. What has happened in this statement? First of all, whatever ptrA is pointing to will
be assigned to the location where ptrB is pointing to. When the loop starts, these pointers are pointing to the
start of the array. So the first character of strA will be copied to the first character of strB. Afterwards, the
pointers will be incremented, not the values they are pointing to. Therefore, ptrA is pointing to the 2nd element of
the array strA and ptrB is pointing to the 2nd element of the array strB. In the 2nd repetition, the loop condition will
be tested. If ptrA is not pointing to a null character the assignment for the 2nd element of the array takes place
and so on till the null character is reached. So all the characters of array strA are copied to array strB. Is this
program complete? No, the array strB is not containing the null character at the end of the string. Therefore, we
have explicitly assigned the null character to strB. Do we need to increment the array pointer? No, simply due
to the fact that in the assignment statement ( *ptrA++ = *ptrB++;), the pointers are incremented after the
assignment. This program now successfully copies one string to other using only pointers. We can also write a
function for the string copy. The prototype of the function will be as:

void myStringCopy (char *destination, const char *source) ;


This function takes two arguments. The first one is a pointer to a char while second argument is a const
pointer to char. The destination array will be changed and all the characters from source array are copied to
destination. At the same time, we do not want that the contents of source should be changed. So we used the
keyword const with it. The keyword const makes it read only and it can not be changed accidentally. If we try to
change the contents of source array, the compiler will give an error. The body is same, as we have seen in the
above program.
This function will not return anything as we are using pointers. It is automatically call by reference.
Whenever arrays are passed to functions, a reference of the original array is passed. Therefore, any change in
the array elements in the function will change the actual array. The values will be written to the original array. If
these are simple variables, we will have to send the address and get the called program to change it. Therefore,
we do not need to return anything from this function after successfully copying an array into the other.
 
Here is the code of the function. Write a program to test this function.

void myStringCopy (char *destination, const char *source)


{
            while(*source != ‘\0’)
            {
                         *destination++ = *source++;
            }
            *destination = ‘\0’;
}
We can also write the string copy function using arrays. Here is the code of the myStringCopy function
using arrays notation.

  void myStringCopy(char dest[], char source[])


   {
        int i = 0;
 
        while (source[i] != '\0')
        {
           dest[i] = source[i];
           i++;
        }
        dest[i] = '\0';
    }

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

 Increment and decrement the pointers while using  arrays

 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

 Use key word const with pointers to avoid unwanted changes

 The name of array is a constant pointer. It cannot be reassigned

You might also like