Character pointers and strings are where C stops being forgiving. One missing null terminator or one misread *p++, and an easy-looking output question is gone. The 12 questions here start from a plain declaration check and move through GATE, ISRO, HPSC, Hexaware and TCS output traces, so attempt each one on paper before reading its explanation. Question headings link to their own solved pages where one exists, and the C Language learn module holds the rest of the topic.
What a C string actually is
C has no built-in string type. A C string is a character array whose end is marked by \0, so "Hello" occupies six bytes: 'H', 'e', 'l', 'l', 'o', \0. Both char str[] = "Hello"; and char *str = "Hello"; are valid declarations, but the array has writable storage while the pointer refers to a string literal that must not be modified.
Q1. String declaration
Which of the following is a correct way to declare a string in C?
(a) char *str = "Hello";
(b) string str = "Hello";
(c) char str[] = "Hello";
(d) Both A and C
Answer: (d) Both A and C. Option (a) points to a string literal, so do not write through it. Option (c) creates a writable array. Option (b) fails because string is not a C type. Prefer an array when the characters must change.
Q2. HPSC 2015
Strings are character arrays. The last index of it contains the null-terminated character:
(a) \t (b) \n (c) \0 (d) \1 (e) Question not attempted
Answer: (c) \0. Its numeric value is zero, and functions such as strlen, strcmp, and printf with %s use it to find the end. \t is tab, \n is newline, and \1 is the byte value 1. Option (e) belongs to the exam's answer-sheet format.
The terminator decides everything
A character array without \0 is only a sequence of bytes, not a valid string. Include \0, and a brace initialiser can represent exactly the same bytes as a double-quoted string.
Q3. Hexaware 2025
What will be the output of the following code?
char str[] = {'h', 'e', 'l', 'l', 'o'};
printf("%s", str);(a) hello
(b) Undefined Behavior
(c) Compilation error
(d) Runtime error
Answer: (b) Undefined Behavior. The five-element array has no terminator. %s reads beyond it until a zero byte happens to appear. It may show garbage, appear correct, or crash. The code compiles, and no particular runtime failure is guaranteed.
Q4. Hexaware 2023
What will be the output of the following code?
char str1[] = "Coding";
char str2[] = {'C', 'o', 'd', 'i', 'n', 'g', '\0'};
if (strcmp(str1, str2) == 0)
printf("Same");
else
printf("Not Same");(a) Same
(b) Not Same
(c) Compilation error
(d) Runtime error
Answer: (a) Same. Both arrays hold the same seven bytes, terminator included. strcmp reaches the common \0 and returns 0. Q3 breaks for one reason only: its brace initialiser omits that final byte.
Pointer arithmetic on a string, the GATE classics
A char * advances one byte at a time. Since characters also have integer values, exam questions can combine a character difference with pointer arithmetic. Build an index table before calculating.
Q5. GATE 2015
Consider the following C program segment.
#include <stdio.h>
int main()
{
char s1[7] = "1234", *p;
p = s1 + 2;
*p = '0';
printf("%s", s1);
}What will be printed by the program?
(a) 12 (b) 120400 (c) 1204 (d) 1034
Answer: (c) 1204. The seven cells start as '1','2','3','4','\0','\0','\0'. p = s1 + 2 selects s1[2], so *p = '0' replaces '3'. Printing '1','2','0','4','\0' stops at index 4. Character '0' is not \0.
![Memory diagram for Q5 with seven cells labelled s1[0] to s1[6]. Before, the cells are '1','2','3','4','\0','\0','\0', with an arrow labelled "p = s1 + 2" at s1[2] = '3'. After "*p = '0'", they are '1','2','0','4','\0','\0','\0', with s1[2] highlighted and the caption "printf(\"%s\", s1) stops at s1[4], output 1204".](https://kgai.blob.core.windows.net/blog-assets/blog_asset_1784142916912_dslasa.jpg)
Q6. GATE 2011
What does the following fragment of C program print?
char c[] = "GATE2011";
char *p = c;
printf("%s", p + p[3] - p[1]);(a) GATE2011 (b) E2011 (c) 2011 (d) 011
Answer: (c) 2011. The relevant indexes are 1:'A', 3:'E', and 4:'2'. Their values are 65 and 69, so p + p[3] - p[1] = p + 69 - 65 = p + 4. That points to c[4], and %s prints from there. A character difference can act as a pointer offset.
When the subscript flips: 2[p] is legal C
The expression a[i] means *(a + i). Addition commutes, so i[a] selects the same element. It looks odd, but it is valid C.
Q7. ISRO 2017
Consider the following C function.
#include <stdio.h>
int main(void)
{
char c[] = "ICRBCSIT17";
char *p = c;
printf("%s", c + 2[p] - 6[p] - 1);
return 0;
}The output of the program is
(a) SI (b) IT (c) TI (d) 17
Answer: (d) 17. Here 2[p] is p[2] = 'R' = 82, while 6[p] is p[6] = 'I' = 73. Thus c + 82 - 73 - 1 = c + 8, pointing at the '1' in "17". Options (a) to (c) cannot occur at all, because %s prints to the end of the string: every starting cell yields a suffix such as IT17, never a two-letter fragment.
Loops that quietly build an empty string
Before tracing a whole string loop, read its very first assignment. If that write lands \0 in index 0, nothing the loop does afterwards reaches %s, and the remaining iterations are decoration.
Q8. GATE 2008
What is the output printed by the following C code?
#include <stdio.h>
int main()
{
char a[6] = "world";
int i, j;
for (i = 0, j = 5; i < j; a[i++] = a[j--]);
printf("%s\n", a);
}(a) dlrow (b) Null String (c) dlrld (d) worow
Answer: (b) Null String. The semicolon leaves an empty loop body; copying happens in the update. First, a[0] = a[5] = '\0'. Later updates write a[1] = 'd' and a[2] = 'l', but %s stops at a[0]. Option (a) comes from imagining a reversal.
Q9. GATE 2004
Consider the following C program segment:
char p[20];
char *s = "string";
int length = strlen(s);
int i;
for (i = 0; i < length; i++)
p[i] = s[length - i];
printf("%s", p);The output of the program is
(a) gnirts (b) gnirt (c) string (d) no output is printed
Answer: (d) no output is printed. length is 6. At i = 0, the code copies s[6], the terminator, into p[0]. Printing therefore stops before any visible character. A correct reversal would read s[length - i - 1]; option (a) describes the intention, not the program.
Copies that overlap and arrays of pointers
These traces test two different details: a copy loop that leaves an old tail behind, and the precedence difference between ++*p and *p++.
Q10. GATE 2025
Consider the following C program:
#include <stdio.h>
void stringcopy(char *, char *);
int main() {
char a[30] = "@#Hello World!";
stringcopy(a, a + 2); // Copy from a+2 to a
printf("%s\n", a);
return 0;
}
void stringcopy(char *s, char *t) {
while (*t)
*s++ = *t++;
}Which ONE of the following will be the output of the program?
(a) @#Hello World! (b) Hello World! (c) ello World! (d) Hello World!d!
Answer: (d) Hello World!d! The loop copies the 12 characters at old positions 2 to 13 into positions 0 to 11. Each source is read before being overwritten. At the old terminator at index 14, the loop stops without copying it. Positions 12 and 13 still hold d and !, so printing ends at index 14. Option (b) requires copying \0.
Q11. TCS 2025
int main()
{
char *s[] = { "knowledge","is","power"};
char **p;
p = s;
printf("%s ", ++*p);
printf("%s ", *p++);
printf("%s ", ++*p);
getchar();
return 0;
}(a) nowledge nowledge s
(b) knowledge is power
(c) knowledge knowledge i
(d) power is knowledge
Answer: (a) nowledge nowledge s. Initially p points at s[0]. First, ++*p advances the pointer stored in s[0], so it prints nowledge. Next, *p++ yields that same pointer before advancing p to s[1], so it again prints nowledge. Finally, ++*p advances the pointer in s[1] past 'i', producing s. Precedence traces like this one are a TCS favourite, and the TCS NQT exam structure shows where those rounds sit in the hiring process.
sizeof a pointer is not sizeof the array
sizeof(arr) measures the complete array object. sizeof(p) measures only the pointer variable, whose width depends on the platform. This is also why passing an array to a function loses its length information. The box-by-box drawing method behind these traces is worked out in Pointers in C for GATE.
Q12. TCS 2025
Predict the output.
#include <stdio.h>
int main(void)
{
char arr[] = {1, 2, 3};
char *p = arr;
printf("%zu", sizeof(p) + sizeof(arr));
return 0;
}Choose 0 if the output depends on the compiler/platform.
Choose 1 if there is an error in the code.
(a) 0 (b) 2 (c) 1 (d) 3
Answer: (a) 0. sizeof(arr) is 3 because the array has three char elements and each character occupies one byte. sizeof(p) is platform-dependent, commonly 4 or 8, making the sum 7 or 11. The question instructs you to choose 0 for that case. The code itself is legal.
The short version and your next step
A C string is a character array ending in
\0. The terminator controls every string operation.Character differences can become pointer offsets, as Q6 and Q7 show.
Check the first assignment before tracing a loop. Q8 and Q9 become easy once you do.
A hand-written copy that skips
\0can expose the old tail, as in Q10.sizeof(array)measures the array, whilesizeof(pointer)depends on the platform.
About 40 more character-pointer and string questions sit in KnowledgeGate's C question bank. To build the topic from the basics instead of one trace at a time, work through the C Programming Course, or browse the wider coding and skill development courses.




