Pointer Comparisons/Pointers and Arrays


1.1.Pointer Comparisons

Pointers may be compared by using relational operators, such as ==, <, and >. However, for the outcome of a pointer comparison to be meaningful, the two pointers normally must have some relationship to each other. For example, if p1 and p2 are pointers that point to two separate and unrelated variables, then any comparison between p1 and p2 is generally meaningless. However, if p1 and p2 point to variables that are related to each other, such as elements of the same array, then p1 and p2 can be meaningfully compared. Later in this chapter, you will see a sample program that does this.

1.2.Pointers and Arrays

In C++, there is a close relationship between pointers and arrays. In fact, frequently a pointer and an array are interchangeable. In this section, you will see how pointers and arrays relate. To begin, consider this fragment:
char str[80];
char *p1;
p1 = str;
Here, str is an array of 80 characters and p1 is a character pointer. However, it is the third line that is of interest. In this line, p1 is assigned the address of the first element in the str array. (That is, after the assignment, p1 will point to str[0].) Here’s why: In C++, using the name of an array without an index generates a pointer to the first element in the array. Thus the assignment p1 = str assigns the address of str[0] to p1. This is a crucial point to understand: When an unindexed array name is used in an expression, it yields a pointer to the first element in the array. Since, after the assignment, p1 points to the beginning of str, you may use p1 to access elements in the array. For example, if you want to access the fifth element in
str, you could use
str[4]
or
*(p1+4)
Both statements will return the fifth element. Remember, array indices start at zero, so when str is indexed, a 4 is used to access the fifth element. A 4 is also added to the pointer p1 to get the fifth element, because p1 currently points to the first element of str. The parentheses surrounding p1+4 are necessary because the * operation has a higher priority than the + operation. Without the parentheses, the expression would first find the value pointed to by p1 (the first location in the array) and then add 4 to it. In effect, C++ allows two methods of accessing array elements: pointer arithmetic and array indexing. This is important because pointer arithmetic can sometimes be faster than array indexing—especially when you are accessing an array in strictly sequential order. Since speed is often a consideration in programming, the use of pointers to access array elements is very common in C++ programs. Also, you can sometimes write tighter code by using pointers rather than array indexing. To get the flavor of the difference between using array indexing and pointer arithmetic, two versions of the same program will be shown next. The program extracts words, separated by spaces, from a string. For example, given "Hello Tom," the program would extract "Hello" and "Tom." Programmers typically refer to delineated character sequences as tokens, and the process of extracting tokens is generally called tokenizing. The program scans the input string, copying characters from the string into another array, called token, until a space is encountered. It then prints the token and repeats the process until the null at the end of the string is reached. For example, if you enter This is a test. the program displays the following:
This
is
a
test.
Here is the pointer version of the tokenizing program:
// Tokenizing program: pointer version.
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
char str[80];
char token[80];
char *p, *q;
cout << "Enter a sentence: ";
gets(str);
p = str;
// Read a token at a time from the string.
while(*p) {
q = token; // set q pointing to start of token
/* Read characters until either a space or the
null terminator is encountered. */
while(*p!=' ' && *p) {
*q = *p;
q++; p++;
}
if(*p) p++; // advance past the space
*q = '\0'; // null terminate the token
cout << token << '\n';
}
return 0;
}
Here is the array-indexing version:
// Tokenizing program: array-indexing version.
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
char str[80];
char token[80];
int i, j;
cout << "Enter a sentence: ";
gets(str);
// Read a token at a time from the string.
for(i=0; ; i++) {
/* Read characters until either a space or the
null terminator is encountered. */
for(j=0; str[i]!=' ' && str[i]; j++, i++)
token[j] = str[i];
token[j] = '\0'; // null terminate the token
cout << token << '\n';
if(!str[i]) break;
}
return 0;
}

Because of the way some C++ compilers generate code, these two programs may not be equivalent in performance. Generally, it takes more machine instructions to index an array than it does to perform arithmetic on a pointer. Consequently, in professionally written C++ code, it is common to see the pointer version used more frequently. However, as a beginning C++ programmer, feel free to use array indexing until you are comfortable with pointers.
Share on Google Plus