Introduction to C Language | Lesson 5: Detailed Explanation of Arrays – From Beginner to Pro
1.π― Introduction: Why Learn Arrays?
Hello everyone! Today we will learn a very important concept in C language – arrays.
Imagine this scenario: you are a teacher who needs to manage the grades of 50 students in your class. If you follow the knowledge learned before, you would need to define 50 different variables:
int student1, student2, student3, ..., student50; // Oh my, that's terrifying!
This approach is not only cumbersome but also nearly impossible to maintain. Arrays are the savior that solves this problem!
Arrays are like numbered lockers:
- β’ Each locker has a number (index)
- β’ The items stored in each locker are of the same type
- β’ You can quickly find the corresponding locker by its number
2.π‘ What is an Array?
An Array: is a collection of elements of the same data type, stored contiguously in memory and accessed via an index.
(1) Basic Syntax of Arrays
data_type array_name[array_size];
For example:
int scores[5]; // Create an array named scores that can store 5 integers
char name[20]; // Create an array named name that can store 20 characters
float prices[10]; // Create an array named prices that can store 10 floating-point numbers
(2) π Core Characteristics of Arrays
- 1. Index starts from 0: The number of the first element is 0, not 1!
- 2. Uniform type: All elements in the array must be of the same type
- 3. Fixed size: The size of the array cannot be changed after creation
- 4. Contiguous storage: Elements are stored next to each other in memory
3.π Practical Exercise with One-Dimensional Arrays
(1) Problem: Pain Points of Traditional Methods
Letβs first look at the problems encountered without using arrays:
#include <stdio.h>
// Define a variable for each student (very tedious!)
int student1 = 85; // Grade of student 1
int student2 = 92; // Grade of student 2
int student3 = 78; // Grade of student 3
int num; // Store the user input student number
int main()
{
printf("Please enter the student number (1-3):");
scanf("%d", &num);
// Need to use switch to handle each student, very verbose
switch(num)
{
case 1:
printf("The grade of student 1 is: %d\n", student1);
break;
case 2:
printf("The grade of student 2 is: %d\n", student2);
break;
case 3:
printf("The grade of student 3 is: %d\n", student3);
break;
default:
printf("No such student\n");
break;
}
return 0;
}
Problems with this approach:
- β’ If there are 100 students, do I need to write 100 variables? That’s terrifying!
- β’ Code duplication, hard to maintain
- β’ Cannot use loops, extremely inefficient
(2) Solution: Use Arrays
#include <stdio.h>
int main()
{
// Define an array that can store the grades of 5 students
int students[5]; // Index range: 0, 1, 2, 3, 4
int i; // Loop counter
int num; // User input student number
int studentCount = 5; // Number of students, easy to modify later
// Step 1: Use a loop to input all students' grades
printf("=== Grade Entry System ===\n");
for(i = 0; i < studentCount; i++)
{
printf("Please enter the grade of student %d:", i + 1);
// students[i] represents the element at index i in the array
// &students[i] represents the address of the i-th element in memory
scanf("%d", &students[i]);
}
// Step 2: Query a specific student's grade
printf("\n=== Grade Query System ===\n");
printf("Please enter the student number to query (1-%d):", studentCount);
scanf("%d", &num);
// Validate input
if(num >= 1 && num <= studentCount)
{
// Important: Student number starts from 1, but array index starts from 0, so subtract 1
printf("The grade of student %d is: %d\n", num, students[num-1]);
}
else
{
printf("The entered student number does not exist! Please enter a number between 1-%d\n", studentCount);
}
// Step 3: Display all students' grades
printf("\n=== All Students' Grades ===\n");
for(i = 0; i < studentCount; i++)
{
printf("Student %d: %d points\n", i + 1, students[i]);
}
return 0;
}
Example Output:
=== Grade Entry System ===
Please enter the grade of student 1: 85
Please enter the grade of student 2: 92
Please enter the grade of student 3: 78
Please enter the grade of student 4: 96
Please enter the grade of student 5: 83
=== Grade Query System ===
Please enter the student number to query (1-5): 3
The grade of student 3 is: 78
=== All Students' Grades ===
Student 1: 85 points
Student 2: 92 points
Student 3: 78 points
Student 4: 96 points
Student 5: 83 points
(3) π¨ Array Initialization Methods
#include <stdio.h>
int main()
{
// Method 1: Direct initialization at definition
int arr1[5] = {10, 20, 30, 40, 50};
// Method 2: Partial initialization (unspecified elements are automatically set to 0)
int arr2[5] = {10, 20}; // Result: {10, 20, 0, 0, 0}
// Method 3: Let the compiler automatically calculate the array size
int arr3[] = {1, 2, 3, 4}; // Compiler automatically determines it has 4 elements
// Method 4: Initialize all to 0 (common trick)
int arr4[5] = {0}; // Result: {0, 0, 0, 0, 0}
// Method 5: Assign values one by one after definition
int arr5[3];
arr5[0] = 100;
arr5[1] = 200;
arr5[2] = 300;
// Display the contents of each array
printf("arr1: ");
for(int i = 0; i < 5; i++) printf("%d ", arr1[i]);
printf("\n");
printf("arr2: ");
for(int i = 0; i < 5; i++) printf("%d ", arr2[i]);
printf("\n");
printf("arr3: ");
for(int i = 0; i < 4; i++) printf("%d ", arr3[i]);
printf("\n");
return 0;
}
4.π Array Sorting: Detailed Explanation of Bubble Sort
Sorting is a classic problem in array operations. Letβs delve into arrays through bubble sort:
#include <stdio.h>
int main() {
int numbers[8]; // Array to store 8 numbers
int i, j, temp; // Loop variables and temporary variable
int size = 8; // Array size, easy to modify
// Step 1: Input data
printf("=== Bubble Sort Demonstration Program ===\n");
printf("Please enter %d integers:\n", size);
for(i = 0; i < size; i++) {
printf("Number %d: ", i + 1);
scanf("%d", &numbers[i]);
}
// Display original array
printf("\nOriginal array: ");
for(i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n\n");
// Step 2: Bubble sort algorithm
printf("=== Sorting Process Demonstration ===\n");
// Outer loop: controls the number of sorting rounds (needs size-1 rounds)
for(i = 0; i < size - 1; i++) {
printf("Round %d of sorting:\n", i + 1);
// Record whether a swap occurred this round
int swapped = 0;
// Inner loop: compare adjacent elements each round
for(j = 0; j < size - 1 - i; j++) {
printf(" Comparing %d and %d", numbers[j], numbers[j+1]);
// If the first number is greater than the second, swap them
if(numbers[j] > numbers[j+1]) {
// Three-step swap method
temp = numbers[j]; // 1. Store the first number in a temporary variable
numbers[j] = numbers[j+1]; // 2. Assign the second number to the first
numbers[j+1] = temp; // 3. Assign the temporary variable to the second
swapped = 1; // Mark that a swap occurred
printf(" β Swapped!");
} else {
printf(" β No swap");
}
printf("\n");
}
// Display the result after this round of sorting
printf(" Result after round %d: ", i + 1);
for(int k = 0; k < size; k++) {
printf("%d ", numbers[k]);
}
printf("\n");
// Optimization: If no swaps occurred this round, the array is already sorted
if(!swapped) {
printf(" Early exit: Array is already sorted!\n");
break;
}
printf("\n");
}
// Step 3: Output final result
printf("=== Final Result ===\n");
printf("Sorted array: ");
for(i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
(1) π€ In-Depth Analysis of Bubble Sort Principle
Why is it called “Bubble” Sort?
Just like bubbles in water slowly rise to the surface, larger numbers will also “bubble” to the end of the array during each comparison.
Detailed Process (using the array [5,2,8,1] as an example):
Initial state: [5, 2, 8, 1]
Round 1: Let the largest number "bubble" to the end
Compare 5 and 2: 5>2, swap β [2, 5, 8, 1]
Compare 5 and 8: 5<8, no swap β [2, 5, 8, 1]
Compare 8 and 1: 8>1, swap β [2, 5, 1, 8]
End of round 1: [2, 5, 1, 8] (largest 8 is now at the end)
Round 2: Let the second largest number "bubble" to the second last position
Compare 2 and 5: 2<5, no swap β [2, 5, 1, 8]
Compare 5 and 1: 5>1, swap β [2, 1, 5, 8]
End of round 2: [2, 1, 5, 8] (second largest 5 is also in place)
Round 3: Continue processing the remaining numbers
Compare 2 and 1: 2>1, swap β [1, 2, 5, 8]
End of round 3: [1, 2, 5, 8] (sorting complete!)
5.π Two-Dimensional Arrays: The World of Data Tables
(1) What is a Two-Dimensional Array?
If a one-dimensional array is a row of lockers, thena two-dimensional array is a table of lockers, with both rows and columns.
// Imagine a table with 3 rows and 4 columns
int table[3][4];
// This can be understood as:
// table[0][0] table[0][1] table[0][2] table[0][3] β Row 0
// table[1][0] table[1][1] table[1][2] table[1][3] β Row 1
// table[2][0] table[2][1] table[2][2] table[2][3] β Row 2
// β β β β
// Column 0 Column 1 Column 2 Column 3
(2) Practical Example of Two-Dimensional Arrays: Grade Management System
#include <stdio.h>
int main()
{
// Define a 3x4 two-dimensional array
// 3 students, each with grades for 4 subjects
int scores[3][4] = {
{85, 92, 78, 96}, // Grades of student 0 (Chinese, Math, English, Physics)
{90, 87, 95, 88}, // Grades of student 1
{92, 85, 89, 94} // Grades of student 2
};
// Subject names (for display)
char subjects[4][10] = {"Chinese", "Math", "English", "Physics"};
int studentCount = 3; // Number of students
int subjectCount = 4; // Number of subjects
// Display grade table
printf("=== Student Grade Table ===\n");
printf("Student\t");
// Print header
for(int j = 0; j < subjectCount; j++) {
printf("%s\t", subjects[j]);
}
printf("Average Score\n");
// Use nested loops to traverse the two-dimensional array
for(int i = 0; i < studentCount; i++) // Outer loop: traverse students (rows)
{
printf("Student %d\t", i + 1);
int totalScore = 0; // Calculate total score
// Inner loop: traverse each student's grades (columns)
for(int j = 0; j < subjectCount; j++)
{
printf("%d\t", scores[i][j]);
totalScore += scores[i][j]; // Accumulate scores
}
// Calculate and display average score
double average = (double)totalScore / subjectCount;
printf("%.1f\n", average);
}
// Calculate average score for each subject
printf("\n=== Average Scores for Each Subject ===\n");
for(int j = 0; j < subjectCount; j++) {
int subjectTotal = 0;
// Calculate total score for the j-th subject
for(int i = 0; i < studentCount; i++) {
subjectTotal += scores[i][j];
}
double subjectAverage = (double)subjectTotal / studentCount;
printf("%s Average Score: %.1f\n", subjects[j], subjectAverage);
}
return 0;
}
Output Result:
=== Student Grade Table ===
Student Chinese Math English Physics Average Score
Student 1 85 92 78 96 87.8
Student 2 90 87 95 88 90.0
Student 3 92 85 89 94 90.0
=== Average Scores for Each Subject ===
Chinese Average Score: 89.0
Math Average Score: 88.0
English Average Score: 87.3
Physics Average Score: 92.7
(3) π§ Memory Layout of Two-Dimensional Arrays
This is a common source of confusion for beginners! Two-dimensional arrays are actually stored contiguously in memory by row:
int arr[2][3] = {{1,2,3}, {4,5,6}};
// To us, it looks like this:
// 1 2 3 β Row 0
// 4 5 6 β Row 1
// But in memory, it is stored like this:
// [1][2][3][4][5][6] β A straight line!
This explains why we can access all elements of a two-dimensional array using a one-dimensional array approach.
6.π Constant Arrays: A Repository of Unmodifiable Data
Sometimes we need some data that cannot be modified during program execution, such as the names of days of the week, month names, etc.:
#include <stdio.h>
int main()
{
// Define a constant array using the const keyword
const char weekDays[7][10] = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
};
// Hexadecimal character reference table
const char hexChars[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
// Using the week array
int day;
printf("Please enter what day it is today (0-6, 0 means Sunday): ");
scanf("%d", &day);
if(day >= 0 && day <= 6) {
printf("Today is %s\n", weekDays[day]);
}
// Convert decimal to hexadecimal using the hexadecimal array
int decimal = 255;
printf("\nDecimal %d converted to hexadecimal: ", decimal);
// Convert decimal to hexadecimal
if(decimal == 0) {
printf("0");
} else {
char hexResult[20];
int index = 0;
int temp = decimal;
// Conversion process
while(temp > 0) {
hexResult[index] = hexChars[temp % 16];
temp = temp / 16;
index++;
}
// Output in reverse (because the calculation is from low to high)
for(int i = index - 1; i >= 0; i--) {
printf("%c", hexResult[i]);
}
}
printf("\n");
// The following line will cause a compilation error because constant arrays cannot be modified
// weekDays[0] = "Modified Content"; // Compilation error!
return 0;
}
Advantages of Constant Arrays:
- β’ Safety: Prevents accidental modification of important data
- β’ Memory Efficiency: Stored in read-only memory, saving memory
- β’ Code Clarity: Clearly indicates that this data should not be modified
7.π Character Arrays and Strings: The Art of Text Processing
(1) Character vs String: Don’t Get Confused!
This is a common mistake for beginners:
char single_char = 'A'; // Character: single quotes, can only store one character
char string_array[] = "Hello"; // String: double quotes, can store multiple characters
Key Points:
- β’ Character uses single quotes
<span>'A'</span> - β’ String uses double quotes
<span>"Hello"</span>
(2) The Essence of Strings Revealed
A string is essentially a character array terminated by a special character ‘\0’:
#include <stdio.h>
int main()
{
// Method 1: Manually create a string (tedious but intuitive)
char str1[] = {'H', 'e', 'l', 'l', 'o', '\0'};
// Method 2: Use string literal (recommended, compiler automatically adds '\0')
char str2[] = "Hello";
// Method 3: Specify array size
char str3[20] = "Hello"; // Remaining space will be automatically initialized to '\0'
// Verify string content
printf("str1: %s\n", str1); // Output: Hello
printf("str2: %s\n", str2); // Output: Hello
printf("str3: %s\n", str3); // Output: Hello
// View the internal structure of the string (this is important!)
printf("\n=== Internal Structure Analysis of str2 ===\n");
for(int i = 0; i <= 5; i++) { // Note: must include the terminator '\0'
if(str2[i] == '\0') {
printf("Position %d: '\0' (string terminator, ASCII code: %d)\n", i, str2[i]);
} else {
printf("Position %d: '%c' (ASCII code: %d)\n", i, str2[i], str2[i]);
}
}
// Why is '\0' needed? Because C needs to know where the string ends
printf("\n=== Why is the Terminator Needed? ===\n");
char incomplete[] = {'A', 'B', 'C'}; // Character array without terminator
// printf("%s\n", incomplete); // Dangerous! May output garbage
return 0;
}
(3) Traps and Solutions for String Input and Output
#include <stdio.h>
int main()
{
char name[50];
char fullName[100];
// Method 1: Use scanf (limited)
printf("Please enter your name:");
scanf("%s", name); // Note: no need for & before name!
printf("Hello, %s!\n", name);
// Problem with scanf: stops at spaces
printf("\n=== Demonstration of scanf Problem ===\n");
printf("If you enter 'Zhang San', scanf will only read 'Zhang'\n");
// Clear input buffer (important technique!)
while(getchar() != '\n');
// Method 2: Use fgets to read the complete line (recommended)
printf("\nPlease enter your full name (can include spaces):");
fgets(fullName, sizeof(fullName), stdin);
printf("Your full name is: %s", fullName); // fgets retains the newline character
// Method 3: Use scanf with format string to read strings with spaces
char address[200];
printf("Please enter your address:");
scanf(" %[^
]", address); // Read all characters except newline
printf("Your address is: %s\n", address);
return 0;
}
Important Reminder:
| Method | Syntax | Advantages | Disadvantages |
| scanf | <span>scanf("%s", name)</span> |
Simple | Stops at spaces |
| fgets | <span>fgets(name, size, stdin)</span> |
Can read spaces | Retains newline character |
| Advanced scanf | <span>scanf(" %[^ |
Can read spaces | Complex syntax |
(4) π― Practical Project for String Processing
#include <stdio.h>
#include <string.h> // String processing function library
int main()
{
char text[200];
int letterCount = 0; // Letter count
int digitCount = 0; // Digit count
int spaceCount = 0; // Space count
int otherCount = 0; // Other character count
printf("=== String Analysis Program ===\n");
printf("Please enter a piece of text:");
fgets(text, sizeof(text), stdin);
// Analyze each character in the string
printf("\n=== Analysis Result ===\n");
for(int i = 0; text[i] != '\0'; i++) {
char c = text[i];
if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
letterCount++;
} else if(c >= '0' && c <= '9') {
digitCount++;
} else if(c == ' ') {
spaceCount++;
} else if(c != '\n') { // Exclude newline character
otherCount++;
}
}
// Display statistics results
printf("Input text: %s", text);
printf("Letter count: %d\n", letterCount);
printf("Digit count: %d\n", digitCount);
printf("Space count: %d\n", spaceCount);
printf("Other character count: %d\n", otherCount);
printf("Total character count (excluding newline): %d\n", letterCount + digitCount + spaceCount + otherCount);
// String length (using library function)
int length = strlen(text) - 1; // Subtract 1 to exclude the newline character added by fgets
printf("String length: %d\n", length);
return 0;
}
8.π¨ Common Errors and Debugging Techniques
(1) Array Out-of-Bounds Error (Most Common!)
int arr[5] = {1, 2, 3, 4, 5};
// Correct access: arr[0] to arr[4]
printf("%d\n", arr[0]); // β
Correct
printf("%d\n", arr[4]); // β
Correct
// Incorrect access:
printf("%d\n", arr[5]); // β Out of bounds! May cause program crash
printf("%d\n", arr[-1]); // β Out of bounds!
Debugging Techniques:
// Safe array access function
int safeArrayAccess(int arr[], int size, int index) {
if(index >= 0 && index < size) {
return arr[index];
} else {
printf("Error: Array out of bounds! Index %d exceeds range [0,%d]\n", index, size-1);
return -1; // Return error value
}
}
(2) String-Related Errors
// Error 1: Forgetting to leave space for the terminator
char name[5] = "Hello"; // β "Hello" needs 6 positions (including '\0')
// Correct way:
char name[6] = "Hello"; // β
Correct
// Error 2: Using & with scanf
char str[20];
scanf("%s", &str); // β Error! The array name is already an address.
// Correct way:
scanf("%s", str); // β
Correct
9.π Summary and Advanced Guide
(1) Review of Core Points of This Chapter
- 1. The Essence of Arrays: An ordered collection of data of the same type
- 2. Index starts from 0: This is a characteristic of C language, be sure to remember
- 3. Two-Dimensional Arrays: Understand as “arrays of arrays”, stored by rows
- 4. Strings are character arrays: Ending with ‘\0’ is key
- 5. const Keyword: Protects important data from accidental modification
Learning Points Reminder:
- β’ Array indices start from 0, this is a rule of C language
- β’ Prevent array out-of-bounds, this is the most common programming error
- β’ Understand that strings are character arrays, master string processing techniques
- β’ Multi-dimensional arrays are stored by rows, understanding memory layout is important
(2) Preview of Next Lesson
In the next lesson, we will delve into pointers – the most powerful and challenging feature in C language. Pointers are closely related to arrays, mastering pointers will help you truly understand the essence of C language and lay a solid foundation for subsequent learning of dynamic memory allocation, linked lists, and other advanced data structures.
Remember, arrays are the foundation of data structures in C language, and mastering array operations is crucial for future learning. Practice more, think more, and you will definitely master this important concept!
If you encounter any problems during your learning process, feel free to communicate and discuss. Programming learning requires continuous practice and thinking, and if you persist, you will definitely become a C language expert!π