0 · Recall Warm-up
Answer from memory first. Answers are in the Answer Vault at the bottom.
- What is the address of a[i][j] in
int a[R][C]starting at B? from Lesson 1.5.2 int *pandint *qpoint into one array, 2016 and 2040. What is q − p? from Lesson 1.4.3- What lifetime does a static local variable have? from Lesson 1.3.2
1 · The Hook
🎣
A name like “Asha” or a message like “Train 12951 is late” is a row of characters. Different texts have different lengths, and a function that prints or copies text must know where it stops. C’s answer is a marker character at the end, like the full stop at the end of a sentence.
2 · Predict First
🤔
What does this print?
char s[] = "GATE";
printf("%u %u\n", sizeof(s), strlen(s));
Make a guess in your head. The answer opens Section 3.
3 · Core Concept
💡
Predict First — the answer
Output
5 4
The array holds G, A, T, E and an invisible end marker '\0': 5 bytes. strlen counts the characters before the marker: 4.
Strings and the null character '\0'
A string in C is a char array whose characters are followed by the null character '\0' (value 0). Every string function stops at the first '\0'. The string literal "GATE" therefore occupies 5 bytes.
char arrays vs string literals
char s[] = "GATE";creates a 5-byte array and copies the text into it. You may change it:s[0] = 'L';char *p = "GATE";makes p point to the string literal itself, which is stored in read-only memory.p[0] = 'L';is undefined behavior (often a crash).char s[4] = "GATE";is legal C but leaves no room for '\0', so s is not a string; printing it reads past the end.
strlen vs sizeof
char s[] = "GATE";
char t[10] = "hi";
printf("%u %u %u %u %u\n", sizeof(s), strlen(s), sizeof(t), strlen(t), sizeof("abc"));
Output
5 4 10 2 4
sizeof gives the array’s size in bytes (including '\0' and any unused space). strlen counts characters up to, not including, '\0'. For a char *p, sizeof p is the pointer size (4), whatever it points to.
Printing and the standard functions
printf("%s", p) prints characters from p up to '\0'. With #include <string.h>:
| Function | Does |
|---|---|
strlen(s) | number of characters before \0 |
strcpy(d, s) | copies s (with \0) into d; d must be big enough |
strcat(d, s) | appends s to the end of d |
strcmp(a, b) | compares in dictionary order of character codes: negative, 0, or positive |
strncpy(d, s, n) | copies at most n characters (may not add \0) |
char a[20] = "data";
char b[] = "base";
strcat(a, b);
printf("%s %u\n", a, strlen(a));
strcpy(b, "abc");
printf("%s %d %d %d\n", b, strcmp("abc", "abd") < 0, strcmp(b, "abc"), strcmp("b", "a") > 0);
Output
database 8
abc 1 0 1
Never compare strings with ==: that compares addresses.
Walking a string with a pointer
Most string code moves a pointer until it reaches '\0':
int mylen(const char *s)
{
const char *p = s;
while (*p != '\0')
p++;
return (int)(p - s);
}
int main(void)
{
printf("%d %d\n", mylen("pointer"), mylen(""));
return 0;
}
Output
7 0
p + k is a shorter string
If p points into a string, p + k is the string that starts k characters later; printing it with %s prints the tail. *p + 1 is the character code of *p plus 1 (a different character), not the next character.
char s[] = "abcdef";
char *p = s;
p += 2;
*p = 'X';
printf("%s %s %c %c\n", s, p + 1, *p + 1, *(p - 1));
Output
abXdef def Y b
4 · Visual
char s[] = "GATE2027": 9 bytes (8 characters + the null character). printf("%s", s + 4) prints 2027.
char s[] = "stack"; reversing in place with two indices
index: 0 1 2 3 4 5
start: 's' 't' 'a' 'c' 'k' '\0' i=0 j=4 swap -> 'k' ... 's'
step1: 'k' 't' 'a' 'c' 's' '\0' i=1 j=3 swap
step2: 'k' 'c' 'a' 't' 's' '\0' i=2 j=2 stop (i < j fails)
result: "kcats" ('\0' never moves)
The null character stays at the end; only the characters before it are rearranged.
5 · Worked Examples
Example 1 Easy
What does this print?
char s[] = "GATE2027";
char *p = s + 4;
printf("%s %c %u\n", p, *(s + 1), strlen(p));
Solution
p = s + 4 is the tail "2027". *(s + 1) is 'A'. strlen(p) = 4.
Output
2027 A 4
Example 2 Medium
What does this print?
char s[] = "stack";
int i = 0, j = (int)strlen(s) - 1;
while (i < j) {
char t = s[i];
s[i] = s[j];
s[j] = t;
i++;
j--;
}
printf("%s\n", s);
Solution
See the trace in the Visual section.
Output
kcats
Example 3 GATE
What does this print?
char c[] = "PDS2027";
char *p = c;
printf("%s\n", p + p[2] - p[0]);
Solution
p[2] is 'S' (83) and p[0] is 'P' (80): the difference is 3. p + 3 points at "2027". (Character codes of capital letters are consecutive.)
Output
2027
6 · GATE Traps
⚠️
- A string needs one extra byte for '\0': char s[4] = "GATE" is not a string.
- Writing into a string literal through a char * is undefined behavior; a char array copy is writable.
- sizeof counts the whole array (including \0 and unused space); strlen stops before \0.
- sizeof of a char * is the pointer size, not the text length.
- Compare strings with strcmp, not ==.
- *p + 1 changes the character code; *(p + 1) is the next character.
8 · Memory Hook
🧠
“A string is a sentence that ends with a full stop you cannot see.” Every string function reads until it hits the \0 full stop; forget it and they keep reading into someone else’s memory.
9 · Connect the Dots
Lesson 1.5.1 gave rows of one type; strings are rows of chars with an end marker. Real records mix types: a student has a roll number (int), a grade (char) and a name (string). Next lesson answers: how can one variable bundle values of different types under one name?
10 · Self-Test
GATE format. Try every question before opening the vault.
Q1MCQ1 markOutput
What does this print?
char s[] = "GATE2027";
char *p = s + 4;
printf("%s %c %u\n", p, *(s + 1), strlen(p));
- (A)
GATE A 8 - (B)
2027 A 5 - (C)
2027 G 4 - (D)
2027 A 4
Q2NAT1 marksizeof
What is sizeof("PDS")?
Numerical answer: ________
Q3MCQ1 markLiterals
Which line has undefined behavior?
- (A)
char s[] = "hi"; s[0] = 'H'; - (B)
char s[10] = "hi"; s[5] = 'x'; - (C)
char *p = "hi"; p[0] = 'H'; - (D)
char *p = "hi"; p = "ho";
Q4MCQ2 marksOutput
What does this print?
char s[] = "ABCDE";
char *p = s, *q = s + strlen(s) - 1;
while (p < q) {
*p = *p + 1;
p++;
q--;
}
printf("%s\n", s);
- (A)
BCCDE - (B)
ABCDE - (C)
BCDDE - (D)
BCDEF
Q5MSQ2 marksStrings
Which are true for char t[10] = "hi";?
- (A)
strlen(t)is 2 - (B)
sizeof(t)is 10 - (C)
t[2]is '\0' - (D)
t == "hi"is true
11 · Rule Card
- String = chars + '\0'; "abc" takes 4 bytes.
- char s[] = "…" writable copy; char *p = "…" points to a read-only literal.
- strlen counts before \0; sizeof counts the whole array (or 4 for a pointer).
- strcpy, strcat, strcmp (0, 0, >0), strncpy in string.h; compare with strcmp, not ==.
- %s prints from a pointer up to \0; p + k prints the tail.
- *p + 1 ≠ *(p + 1).
12 · Concept Ledger
Unlocked in this lesson. From here on, these terms may be used.
stringnull character '\0'string literal (read-only)char arraystrlenstrcpystrcatstrcmpstrncpy%s
13 · Answer Vault
Answer Vault
Try the questions first. Open when you are ready to check.
Recall Warm-up
- B + (i·C + j)·4 (row-major, 4-byte ints).
- 6 elements.
- The whole run of the program.
Self-Test
Q1 Answer: (D)1 mark
p starts at index 4; s + 1 is 'A'; strlen("2027") = 4.
Output
2027 A 4
- (A) is wrong: p points into the middle.
- (B) is wrong: strlen does not count \0.
- (C) is wrong: *(s + 1) is the second character.
Re-read: Lesson 1.5.3 — Strings: char arrays, '\0', read-only string literals, strlen vs sizeof, string functions and tracing string code
Q2 Answer: 41 mark
3 characters + \0 = 4.
Re-read: Lesson 1.5.3 — Strings: char arrays, '\0', read-only string literals, strlen vs sizeof, string functions and tracing string code
Q3 Answer: (C)1 mark
p points to a read-only string literal.
- (A) is wrong: s is a writable copy.
- (B) is wrong: Index 5 is inside the 10-byte array.
- (D) is wrong: Re-pointing p is fine.
Re-read: Lesson 1.5.3 — Strings: char arrays, '\0', read-only string literals, strlen vs sizeof, string functions and tracing string code
Q4 Answer: (A)2 marks
p and q meet in the middle: only indices 0 and 1 are increased (A→B, B→C) before p = 2 = q stops the loop.
Output
BCCDE
- (B) is wrong: Two characters change.
- (C) is wrong: Index 2 is never changed.
- (D) is wrong: Only the first half changes.
Re-read: Lesson 1.5.3 — Strings: char arrays, '\0', read-only string literals, strlen vs sizeof, string functions and tracing string code
Q5 Answer: (A) (B) (C)2 marks
== compares addresses, which differ.
- (D) is wrong: Use strcmp to compare contents.
Re-read: Lesson 1.5.3 — Strings: char arrays, '\0', read-only string literals, strlen vs sizeof, string functions and tracing string code