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.