Phase 3 — Arrays, Strings & User-Defined Types
This phase is where C starts becoming much more interesting.
You will learn how C handles collections of data, text, and your own custom data types.
We’ll cover this phase in 10 chapters:
1D Arrays
Array Initialization & Traversal
Multidimensional Arrays
Arrays Passed to Functions
Character Arrays & C Strings
String Input & Safety
<string.h>String FunctionsstructNested Structures & Arrays of Structures
union,enum, andtypedef
Chapter 1 — One-Dimensional Arrays
Question
Given below is a program that:
creates an array of five integers
stores values in it
accesses individual elements
modifies one element
calculates a total
What should be the output?
#include <stdio.h>
int main(void)
{
// Create an array containing five integers.
int marks[5] = {70, 85, 90, 65, 80};
// Change the third element.
marks[2] = 95;
// Calculate the total.
int total = marks[0] + marks[1] + marks[2] + marks[3] + marks[4];
// Print the third mark and total.
printf("Third mark: %d\n", marks[2]);
printf("Total: %d\n", total);
return 0;
}Predict the output before reading further.
Answer
Third mark: 95
Total: 395Step-by-step explanation
An array is a collection of values of the same type stored under one name.
int marks[5];means:
Create an array called
markscapable of holding 5 integers.
The positions are:
marks[0] marks[1] marks[2] marks[3] marks[4]
70 85 90 65 80Critical rule
C arrays use zero-based indexing.
So:
first element → [0]
second → [1]
third → [2]
fourth → [3]
fifth → [4]This:
marks[2] = 95;changes:
90 → 95Therefore:
70 + 85 + 95 + 65 + 80 = 395How to read the important code
Read:
int marks[5]as:
marksis an array of 5 integers.
Read:
marks[2]as:
the element at index 2 of
marks.
Beginner trap
marks[5] does not mean the fifth element.
It means the array has 5 elements, whose valid indexes are 0 through 4.
Key takeaway
An array stores multiple values of the same type, and C arrays start at index
0.
Chapter 2 — Array Initialization and Traversal
Question
What will this program print?
#include <stdio.h>
int main(void)
{
// Create and initialize an array.
int numbers[] = {10, 20, 30, 40, 50};
// Calculate how many elements are in the array.
int count = sizeof(numbers) / sizeof(numbers[0]);
// Visit every element.
for (int i = 0; i < count; i++)
{
printf("%d ", numbers[i]);
}
return 0;
}Answer
10 20 30 40 50Step-by-step explanation
Notice:
int numbers[] = {10, 20, 30, 40, 50};We didn't specify the size.
C counts the initializer:
10
20
30
40
50So the array contains 5 integers.
This expression:
sizeof(numbers)gives the total number of bytes occupied by the array.
This:
sizeof(numbers[0])gives the number of bytes occupied by one integer.
Therefore:
sizeof(numbers) / sizeof(numbers[0])gives the number of elements.
Then:
for (int i = 0; i < count; i++)produces:
i = 0 → numbers[0]
i = 1 → numbers[1]
i = 2 → numbers[2]
i = 3 → numbers[3]
i = 4 → numbers[4]How to read the important code
numbers[i]means:
Give me the array element whose index is currently stored in
i.
This pattern is extremely common in C.
Beginner trap
Don't hard-code the array length when you can calculate it safely:
sizeof(numbers) / sizeof(numbers[0])But remember: this works for an actual array in the scope where it exists. It does not generally work after the array has been passed to a function.
We'll see why later.
Key takeaway
A
forloop plus an index variable is the fundamental way to traverse a C array.
Chapter 3 — Multidimensional Arrays
Question
What will be printed?
#include <stdio.h>
int main(void)
{
// Create a 2D array representing two rows and three columns.
int matrix[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
// Change the middle element of the second row.
matrix[1][1] = 50;
// Print the element at row 2, column 2.
printf("%d\n", matrix[1][1]);
// Print every element.
for (int row = 0; row < 2; row++)
{
for (int col = 0; col < 3; col++)
{
printf("%d ", matrix[row][col]);
}
printf("\n");
}
return 0;
}Answer
50
1 2 3
4 50 6Step-by-step explanation
A 2D array:
int matrix[2][3];can be visualized as:
columns
0 1 2
┌────┬────┬────┐
row 0 │ 1 │ 2 │ 3 │
├────┼────┼────┤
row 1 │ 4 │ 5 │ 6 │
└────┴────┴────┘So:
matrix[1][1]means:
row 1, column 1
which initially contains 5.
Then:
matrix[1][1] = 50;changes it to 50.
The nested loops work like:
row 0:
col 0
col 1
col 2
row 1:
col 0
col 1
col 2How to read the important code
Read:
matrix[row][col]as:
element at this row and this column.
Beginner trap
Again, indexing starts at 0.
For:
int matrix[2][3];valid indexes are:
row: 0, 1
column: 0, 1, 2Key takeaway
A multidimensional array is an array whose elements are themselves arrays.
Chapter 4 — Arrays Passed to Functions
Question
What is the output?
#include <stdio.h>
// Receive an array and its number of elements.
void double_values(int numbers[], int count)
{
// Modify every element.
for (int i = 0; i < count; i++)
{
numbers[i] *= 2;
}
}
int main(void)
{
// Create an array.
int numbers[] = {5, 10, 15};
// Pass the array to the function.
double_values(numbers, 3);
// Print the modified array.
for (int i = 0; i < 3; i++)
{
printf("%d ", numbers[i]);
}
return 0;
}Answer
10 20 30Step-by-step explanation
The important thing here is:
double_values(numbers, 3);The array is passed to the function.
Inside:
void double_values(int numbers[], int count)the parameter looks like an array.
But there is an important C concept hiding underneath:
When an array is passed to a function, the parameter effectively becomes a pointer to its first element.
We'll study the pointer mechanics deeply in Phase 4.
For now, understand the behavior.
The function modifies:
5 → 10
10 → 20
15 → 30The changes remain visible in main.
Why do we pass count?
Because the function cannot reliably determine the original array's number of elements using:
sizeof(numbers)inside the function.
So we commonly write:
function(array, number_of_elements);How to read the important code
void double_values(int numbers[], int count)means:
This function receives access to an integer array and is told how many elements it contains.
Key takeaway
When passing arrays to functions, normally pass the array together with its element count.
Chapter 5 — Character Arrays and C Strings
Question
What will this print?
#include <stdio.h>
int main(void)
{
// Store a string inside a character array.
char name[] = "Alice";
// Change the first character.
name[0] = 'M';
// Print the character array as a string.
printf("%s\n", name);
// Print the size of the character array.
printf("%zu\n", sizeof(name));
return 0;
}Answer
Mlice
6Step-by-step explanation
This:
char name[] = "Alice";creates a character array.
Internally, C stores it approximately as:
'A' 'l' 'i' 'c' 'e' '\0'That final:
'\0'is the null character.
It marks the end of a C string.
Therefore "Alice" requires:
5 characters + 1 null character = 6 bytesThen:
name[0] = 'M';changes:
Alice
↓
MliceExtremely important distinction
A C string is not a special built-in string type.
It is:
A sequence of characters ending with
'\0'.
How to read the important code
char name[]means:
an array of characters.
printf("%s", name);means:
print characters starting at
nameuntil the null character is encountered.
Beginner trap
These are different:
'A'and:
"A"'A' is a character.
"A" is a string containing:
'A' '\0'Key takeaway
A C string is a character array terminated by
'\0'.
Chapter 6 — String Input and Buffer Safety
Question
Why is this version safer than using scanf("%s", name)?
#include <stdio.h>
int main(void)
{
// Create a character buffer that can hold 49 characters plus '\0'.
char name[50];
// Safely read a line of text.
printf("Enter your name: ");
if (fgets(name, sizeof(name), stdin) != NULL)
{
// Print the entered string.
printf("Hello, %s", name);
}
return 0;
}Answer
Because:
fgets(name, sizeof(name), stdin)knows the size of the destination buffer.
It can therefore limit how many characters it reads.
Step-by-step explanation
Suppose:
char name[50];The array has room for 50 characters.
But a C string needs a terminating:
'\0'So fgets ensures it doesn't exceed the available buffer when used this way.
For example:
Alicebecomes approximately:
'A' 'l' 'i' 'c' 'e' '\n' '\0'when the newline fits.
Why scanf("%s", name) can be dangerous
Consider:
char name[10];
scanf("%s", name);If the user enters a very long word, scanf can write beyond the array.
That can cause:
memory corruption
crashes
undefined behavior
security vulnerabilities
Important fgets behavior
fgets may store the newline:
Alice\n\0So sometimes you remove it manually.
Example:
name[strcspn(name, "\n")] = '\0';We'll understand strcspn in the next chapter.
How to read the important code
fgets(name, sizeof(name), stdin)Read it as:
Read a line from standard input into
name, but don't exceed the size of the buffer.
Key takeaway
In C, always think about the size of the destination buffer when reading strings.
Chapter 7 — <string.h> and String Functions
Question
What is the output?
#include <stdio.h>
#include <string.h>
int main(void)
{
// Create two strings.
char first[30] = "Hello";
char second[] = " World";
// Add the second string to the first.
strcat(first, second);
// Create a copy of the resulting string.
char copy[30];
strcpy(copy, first);
// Compare the two strings.
int result = strcmp(first, copy);
// Print string information.
printf("%s\n", first);
printf("%zu\n", strlen(first));
printf("%d\n", result);
return 0;
}Answer
Hello World
11
0Step-by-step explanation
<string.h> provides many standard string functions.
strcat
strcat(first, second);appends second to first.
So:
Hello
+
World
=
Hello WorldThe destination must have enough space.
That's very important.
strcpy
strcpy(copy, first);copies the C string from first into copy.
Now:
first = "Hello World"
copy = "Hello World"Again, the destination must have enough space.
strlen
strlen(first)returns the number of characters before '\0'.
Hello Worldcontains:
5 + 1 + 5 = 11characters.
The terminating '\0' is not counted.
strcmp
strcmp(first, copy)compares the strings.
If they are equal:
0If they differ, the result is negative or positive depending on their lexicographical comparison.
Important functions
| Function | Purpose |
|---|---|
strlen | Get string length |
strcpy | Copy string |
strncpy | Bounded-style copy |
strcat | Append string |
strncat | Append with a limit |
strcmp | Compare strings |
strncmp | Compare limited characters |
strchr | Find a character |
strstr | Find a substring |
strcspn | Find length before characters from a set |
Important safety note
Functions such as:
strcpy()
strcat()do not automatically know how large your destination buffer is.
Incorrect usage can cause buffer overflows.
How to read the important code
strcmp(a, b)means:
Compare the contents of the two strings.
Do not use:
a == bto compare C string contents.
Key takeaway
C's string library works with null-terminated character arrays, so buffer size remains your responsibility.
Chapter 8 — Structures (struct)
Question
What will be printed?
#include <stdio.h>
struct Student
{
// Store the student's name.
char name[20];
// Store the student's age.
int age;
// Store the student's marks.
float marks;
};
int main(void)
{
// Create a structure variable and initialize it.
struct Student student = {"Rahul", 21, 87.5f};
// Modify one member.
student.age = 22;
// Print the structure's data.
printf("%s\n", student.name);
printf("%d\n", student.age);
printf("%.1f\n", student.marks);
return 0;
}Answer
Rahul
22
87.5Step-by-step explanation
A struct allows you to group different types of data together.
We define:
struct Studentwith:
name
age
marksConceptually:
Student
┌────────────────┐
│ name │
│ age │
│ marks │
└────────────────┘Then:
struct Student student;creates one variable of that structure type.
To access a member, use:
student.ageThe dot:
.is called the member access operator.
Why structures matter
Without a structure, you might have:
char name[20];
int age;
float marks;for one student.
For 1,000 students, managing related data becomes messy.
With:
struct Studentyou can have:
struct Student students[1000];which we'll use shortly.
How to read the important code
student.marksmeans:
access the
marksmember belonging tostudent.
Key takeaway
A
structlets you combine related variables, even when they have different types.
Chapter 9 — Nested Structures and Arrays of Structures
Question
What will be printed?
#include <stdio.h>
struct Address
{
// Store the city.
char city[30];
// Store the PIN code.
int pin;
};
struct Student
{
// Store the student's name.
char name[30];
// Store the student's address.
struct Address address;
};
int main(void)
{
// Create an array containing two students.
struct Student students[2] = {
{"Amit", {"Patna", 800001}},
{"Neha", {"Gaya", 823001}}
};
// Modify Neha's PIN code.
students[1].address.pin = 823002;
// Print Neha's information.
printf("%s\n", students[1].name);
printf("%s\n", students[1].address.city);
printf("%d\n", students[1].address.pin);
return 0;
}Answer
Neha
Gaya
823002Step-by-step explanation
Here we have a structure inside another structure.
struct Student
{
char name[30];
struct Address address;
};So a Student contains an Address.
The hierarchy is:
Student
├── name
└── address
├── city
└── pinTherefore:
students[1]means:
second student.
Then:
students[1].addressmeans:
that student's address.
And:
students[1].address.pinmeans:
that student's address's PIN.
This pattern is extremely important
Real programs frequently have structures containing:
other structures
arrays
pointers
strings
configuration data
For example:
Employee
├── name
├── salary
└── address
├── city
└── countryHow to read the important code
Read from left to right:
students[1].address.pinas:
second student → address → PIN.
Key takeaway
Arrays organize multiple objects; structures organize the data belonging to each object.
Chapter 10 — union, enum, and typedef
This chapter contains three related C features.
Question
What will the following program print?
#include <stdio.h>
// Give names to integer constants.
enum Status
{
OFF = 0,
ON = 1
};
// Create a structure type using typedef.
typedef struct
{
char name[20];
enum Status status;
} Device;
// Create a union where members share the same memory.
union Data
{
int number;
float decimal;
};
int main(void)
{
// Create a device using the typedef name.
Device device = {"Sensor", ON};
// Create a union.
union Data data;
// Store an integer in the union.
data.number = 42;
printf("%s\n", device.name);
printf("%d\n", device.status);
printf("%d\n", data.number);
return 0;
}Answer
Sensor
1
42enum
An enumeration:
enum Status
{
OFF = 0,
ON = 1
};creates named integer constants.
Instead of:
int status = 1;we can write:
enum Status status = ON;This makes the code easier to understand.
If values aren't explicitly specified, C normally assigns:
0, 1, 2, 3...typedef
This:
typedef struct
{
char name[20];
enum Status status;
} Device;creates an alias:
Devicefor the anonymous structure type.
Without typedef, you might write:
struct Device device;With this typedef:
Device device;Important distinction
typedef does not create a completely new runtime type.
It creates another name for an existing type.
union
This is particularly important for understanding C's memory model.
union Data
{
int number;
float decimal;
};Unlike a struct, the members of a union share the same storage.
Conceptually:
Structure
struct
┌──────────┐
│ int │
├──────────┤
│ float │
└──────────┘Both members have separate storage.
Union
union
┌──────────┐
│ shared │
│ storage │
└──────────┘The storage is reused by the members.
So:
data.number = 42;stores the integer representation in the union's shared storage.
If you subsequently do:
data.decimal = 3.14f;you overwrite that shared storage.
Beginner trap
Don't think:
union Datameans:
an object containing both an integer and a float simultaneously in separate storage.
It doesn't.
How to read the important code
Device devicemeans:
deviceis a variable using the structure type aliased asDevice.
device.statusmeans:
access its
statusmember.
Key takeaway
structgives members separate storage;unionmakes members share storage;enumgives names to integer constants;typedefgives types convenient aliases.
Phase 3 — Master Picture
At the end of this phase, you should be able to mentally organize C data like this:
C DATA
│
┌────────────┴────────────┐
│ │
Collections Custom types
│ │
┌───┴────┐ ┌─────┼─────┐
│ │ │ │ │
Array String struct union enum
│ │
│ └── char[] + '\0'
│
┌──┴─────────┐
│ │
1D 2D
│ │
└─────┬──────┘
│
Functions
│
array parameter
│
pointer
↓
Phase 4The most important concepts from Phase 3
| Concept | What you should understand |
|---|---|
| Array | Collection of same-type elements |
| Index | Position beginning at 0 |
sizeof | Size in bytes |
| 2D array | Array of arrays |
| Array parameter | Function receives access to array data |
| Character array | Array of char |
| C string | Characters ending in '\0' |
strlen | String length excluding '\0' |
strcpy | Copy a string |
strcat | Append a string |
strcmp | Compare strings |
fgets | Safer bounded line input |
struct | Groups related fields |
. | Access structure member |
| Nested struct | Structure containing another structure |
| Array of structs | Multiple structured objects |
union | Members share storage |
enum | Named integer constants |
typedef | Type alias |
⚠️ Five Things You Should NOT Forget
1. Array indexes start at zero
int a[5];valid:
a[0] a[1] a[2] a[3] a[4]Not:
a[5]2. C strings are not Java strings
There is no built-in:
Stringtype like Java.
Instead:
char name[] = "Alice";is:
'A' 'l' 'i' 'c' 'e' '\0'3. strlen and sizeof are different
For:
char name[] = "Alice";typically:
strlen(name) → 5
sizeof(name) → 6because sizeof includes the terminating '\0', while strlen doesn't.
4. Never forget buffer size
This is dangerous:
char name[10];
scanf("%s", name);because the input may exceed the buffer.
C gives you tremendous control—but you are responsible for memory boundaries.
5. struct is the bridge toward real-world C
Once you combine:
struct
+
array
+
string
+
functionyou can start representing real things:
Student
Employee
Book
Product
User
File
Network packet
Configuration
Database recordAnd when we combine those with pointers and dynamic memory in Phase 4, C becomes dramatically more powerful—and considerably more dangerous.
Phase 4 is where arrays, strings, structures, and memory all connect through pointers.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.