An array of strings that contains no strings — just three pointers. char *arr[] is how C fakes a string list, and reading it correctly requires untangling a declaration that half of all beginners parse backwards. This question from our C Programming Quiz App checks whether you know what arr[1] is before asking what it prints.
The Quiz Question
char *arr[] = {"foo", "bar", "baz"};
printf("%s", arr[1]);
What is printed by this code?
- foo
- bar
- baz
- Compile error
The Correct Answer: bar
char *arr[] declares an array of three char pointers ([] binds tighter than *, so it’s an array of pointers, not a pointer to an array). Each element points at one string literal. arr[1] is the second pointer — aimed at "bar" — and %s follows it, printing characters up to the null terminator. Verified on gcc 13.3 and Apple clang 21, clean under -ansi -Wall -Wextra:
$ gcc -ansi -Wall -Wextra strings.c && ./a.out arr[1] = bar arr[1][0] = b sizeof(arr) = 24
That sizeof is telling: 24 bytes = three 8-byte pointers. The nine characters of string data (plus terminators) live elsewhere — the array holds only addresses.
Why Each Wrong Answer Is Wrong
Why not “foo”?
“foo” is arr[0] — the 1-based-indexing slip. C arrays index from zero, so element 1 is the second entry. (The same off-by-one drives wrong answers in the *(a + 1) question.)
Why not “baz”?
“baz” is arr[2], the last element — the answer if you counted from the end or doubled the off-by-one. With three elements the valid indices are 0, 1, 2.
Why not a compile error?
Everything type-checks: the initializer list has three string literals, each of which decays to a char *; arr[1] is a char *; and %s expects exactly that. One legitimate quibble: pointing non-const char * at string literals is allowed in C (unlike C++11+, where it’s an error), but writing through those pointers would crash — the literals live in read-only memory, as the char array vs string literal question demonstrates the hard way. const char *arr[] is the safer declaration.
Two Levels of Indexing — and What This Layout Buys You
Because arr[1] is itself a pointer, a second subscript reaches individual characters: arr[1][0] is 'b', arr[1][2] is 'r' — arr behaves like a 2-D jagged structure without being one. Compare the two ways to store a string table:
char *arr[] = {"foo", "bar", "baz"}; /* 3 pointers → shared literals */
char arr2[3][4] = {"foo", "bar", "baz"}; /* 3 writable rows of 4 bytes */
The pointer form is compact, rows can have wildly different lengths, and swapping two entries means swapping two pointers — this is why argv, environment lists, and menu tables all use it. The 2-D form owns writable storage but pads every row to the longest. The pointer form’s other superpower is sorting: rearranging pointers instead of copying string bytes is what makes qsort on a string table cheap.
This is also exactly the shape of main‘s second parameter — char *argv[] is an array of pointers to the command-line arguments, and argv[1] being “the first argument” (index 1!) trips people for the same reason this question does.
Frequently Asked Questions
What does char *arr[] declare in C?
An array of pointers to char — [] binds tighter than *. With three string-literal initializers it’s three pointers, each aimed at a literal stored elsewhere. sizeof(arr) is 24 on a 64-bit machine: three 8-byte pointers, no string data.
What is arr[1][0] for char *arr[] = {“foo”, “bar”, “baz”}?
'b'. The first subscript selects the pointer to “bar”; the second indexes into that string. The double subscript works even though arr is not a 2-D array.
Can you modify the strings in a char *arr[] table?
Not the literal-initialized ones — they point into read-only storage, and writing crashes. Use char arr[3][4] for writable rows, or declare the table const char *arr[] to let the compiler enforce the read-only reality.
Related Reading
- Char Array vs String Literal in C – Which One Can You Modify?
- Array Name as Pointer in C – Why *(a + 1) Equals a[1]
- Char Pointer in C – Indexing into a String via Pointer
- Pointers in C – Complete Guide
Recommended Books
- The C Programming Language – Kernighan & Ritchie (India) | Amazon.com
- C Programming: A Modern Approach – K.N. King (India) | Amazon.com
This question is #124 in the C Programming Quiz App — 155 questions with explanations covering pointers, arrays, memory, and more.
Download on Google Play →