Testing Your Pointer Prowess – Solution

The solution for this month’s Exercise is to output the string "I am an excellent C programmer". This task isn’t so simple when you must untie the knot of the dratted double pointer.

The challenge presents four arrays, with array z[] the only one you can use to generate the string:

char *a[] = { "I", "good", "language" };
char *b[] = { "am", "C", "excellent", "an" };
char *c[] = { "a", "programmer", "very" };
char **z[] = { a, b, c };

The key is to reference each array within z[]a[], b[], and c[] — by using double pointer notation to access the strings. Scary! But as I wrote in the challenge post, once you get the first construction down the rest come easy.

Here is my solution:

2025_02-Exercise.c

#include <stdio.h>

int main()
{
    char *a[] = { "I", "good", "language" };
    char *b[] = { "am", "C", "excellent", "an" };
    char *c[] = { "a", "programmer", "very" };
    char **z[] = { a, b, c };

    printf("%s %s %s %s %s %s\n",
            *(*(z+0)+0),
            *(*(z+1)+0),
            *(*(z+1)+3),
            *(*(z+1)+2),
            *(*(z+1)+1),
            *(*(z+2)+1)
          );

    return 0;
}

To unwind the string references in the printf() statement, start from the inside and work your way out. Each array referenced by z[] has an offset:

a[]’s address is z+0
b[]’s address is z+1
c[]’s address is z+2

These values are addresses because z is a double-pointer: **z. To access the array’s data, you must dereference the address:

*(z+0) is a[]
*(z+1) is b[]
*(z+2) is c[]

After dereferencing the array, the next offset represents a string’s address within the array. For example:

*(z+0)+0 is the address of string "I", the first string in a[]
*(z+1)+1 is the address of string "C", the second string in b[]
*(z+2)+2 is the address of string "very", the third string in c[]

As these expressions resolve to addresses, they must be further dereferenced with * to access a specific string’s contents, as well as to match the %s placeholder in the printf() statement:

*(*(z+0)+0) is the string "I"
*(*(z+1)+0) is the string "am"
*(*(z+1)+3) is the string "an"
*(*(z+1)+2) is the string "excellent"
*(*(z+1)+1) is the string "C"
*(*(z+2)+1) is the string "programmer"

That’s the solution.

I hope your solution also met with success. Double-pointers happen often in C and you can’t easily avoid them by trying to fake it with array notation. The more you practice, the better you get at understanding and using this useful convention.

Leave a Reply