Since pointers are variables themselves, they can be stored in arrays just as
other variables can. Let us illustrate by writing a program that will sort a set
of text lines into alphabetic order, a stripped-down version of the UNIX program
sort.

Now we deal with lines of text, which are of different lengths, and which,
unlike integers, can't be compared or moved in a single operation. We need a
data representation that will cope efficiently and conveniently with
variable-length text lines.

This is where the array of pointers enters. If the lines to be sorted are
stored end-to-end in one long character array, then each line can be accessed by
a pointer to its first character. The pointers themselves can bee stored in an
array. Two lines can be compared by passing their pointers to strcmp.
When two out-of-order lines have to be exchanged, the pointers in the pointer
array are exchanged, not the text lines themselves.

This eliminates the twin problems of complicated storage management and high
overhead that would go with moving the lines themselves.

The sorting process has three steps:

read all the lines of input
sort them
print them in order

As usual, it's best to divide the program into functions that match this
natural division, with the main routine controlling the other functions. Let us
defer the sorting step for a moment, and concentrate on the data structure and
the input and output.

The input routine has to collect and save the characters of each line, and
build an array of pointers to the lines. It will also have to count the number
of input lines, since that information is needed for sorting and printing. Since
the input function can only cope with a finite number of input lines, it can
return some illegal count like -1 if too much input is presented.

The output routine only has to print the lines in the order in which they
appear in the array of pointers.

says that lineptr is an array of MAXLINES elements, each
element of which is a pointer to a char. That is, lineptr[i]
is a character pointer, and *lineptr[i] is the character it points to,
the first character of the i-th saved text line.

Since lineptr is itself the name of an array, it can be treated as a
pointer in the same manner as in our earlier examples, and writelines
can be written instead as