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.