Skip to main content

πŸ“ Lesson 6: Arrays and Strings

Master data collection management using C++ arrays, multidimensional structures, and modern string objects.

🎯 Learning Objectives

By the end of this lesson, you will be able to:

  • Declare, initialize, and access elements of one-dimensional and multidimensional arrays.
  • Effectively traverse and process array data using loops and common algorithms (search, sort, find min/max).
  • Differentiate between C-style character arrays and modern C++ std::string objects.
  • Implement common string manipulation techniques, such as parsing, searching, and reversing.

Estimated Time: 60–90 minutes

Project: Build a student grade tracking system that uses 2D arrays to store grades for multiple tests across several students.

In This Lesson

What Are Arrays?

Imagine you have 30 students in a class. Would you create 30 separate variables for their grades? That would be like having 30 separate lockers scattered around the school! Arrays are like a row of lockers - organized, numbered, and easy to access.

Declaring and Initializing Arrays

graph TD A[Array Declaration] --> B[Specify Type] A --> C[Specify Name] A --> D[Specify Size] B --> E[int, double, char, etc.] C --> F[grades, scores, names] D --> G[Fixed size in brackets] G --> H["int grades[5];"]

Array Declaration Examples

// Method 1: Declare then initialize
int scores[5];                    // Creates array of 5 integers
scores[0] = 85;
scores[1] = 92;
scores[2] = 78;
scores[3] = 95;
scores[4] = 88;

// Method 2: Declare and initialize together
int scores[5] = {85, 92, 78, 95, 88};

// Method 3: Let compiler count
int scores[] = {85, 92, 78, 95, 88};  // Size is 5

// Method 4: Partial initialization
int scores[5] = {85, 92};  // Rest are 0: {85, 92, 0, 0, 0}

// Method 5: Initialize all to zero
int scores[5] = {0};  // All elements are 0

πŸ’‘ Modern C++ note: Raw arrays like int scores[5] still work everywhere, but modern C++ usually prefers std::array<int, 5> for a fixed-size collection (it knows its own size and plays nicely with range-based for and the standard algorithms) and std::vector<int> when the size can change. We start with raw arrays to learn the fundamentals, then meet std::vector at the end of the lesson.

Array Indexing: The Key to Access

Arrays use zero-based indexing - like floor numbers in some countries where the ground floor is 0!

Array Memory Layout Memory: 1000 1004 1008 1012 1016 10 [0] 20 [1] 30 [2] 40 [3] 50 [4] ⚠️ Important! Arrays ALWAYS start at index 0

Working with Arrays and Loops

Arrays and loops are best friends - they work together perfectly!

Common Array Operations

const int SIZE = 5;
int numbers[SIZE] = {5, 3, 8, 2, 7};

// 1. Find sum and average
int sum = 0;
for (int i = 0; i < SIZE; i++) {
    sum += numbers[i];
}
double average = static_cast<double>(sum) / SIZE;

// 2. Find maximum value
int max = numbers[0];
for (int i = 1; i < SIZE; i++) {
    if (numbers[i] > max) {
        max = numbers[i];
    }
}

// 3. Search for a value
int target = 8;
bool found = false;
for (int i = 0; i < SIZE; i++) {
    if (numbers[i] == target) {
        found = true;
        cout << "Found at index " << i << '\n';
        break;
    }
}

// 4. Reverse the array
for (int i = 0; i < SIZE/2; i++) {
    int temp = numbers[i];
    numbers[i] = numbers[SIZE-1-i];
    numbers[SIZE-1-i] = temp;
}

Multi-Dimensional Arrays: Tables and Grids

2D arrays are like spreadsheets or chess boards - they have rows and columns!

2D Array: Like a Grid or Table [0] [1] [2] [3] [0] [1] [2] [3] [4] [5] 85 92 78 95 88 91 73 grades[1][2] = 73 Row 1, Column 2

2D Array Examples

// Declare a 3x3 tic-tac-toe board
char board[3][3] = {
    {'X', 'O', 'X'},
    {'O', 'X', 'O'},
    {'X', 'X', 'O'}
};

// Access elements
cout << board[0][0];  // Prints 'X' (top-left)
cout << board[1][1];  // Prints 'X' (center)

// Process with nested loops
for (int row = 0; row < 3; row++) {
    for (int col = 0; col < 3; col++) {
        cout << board[row][col] << " ";
    }
    cout << '\n';
}

// Grade table for multiple students
int grades[4][6] = {
    {85, 92, 78, 95, 88, 91},  // Student 0
    {79, 87, 73, 89, 92, 85},  // Student 1
    {92, 95, 89, 97, 94, 96},  // Student 2
    {76, 82, 71, 85, 79, 80}   // Student 3
};

Character Arrays and C-Style Strings

Before the string class, C++ used character arrays - like spelling words letter by letter!

Working with C-Style Strings

// C-style string declaration
char name[20] = "Alice";     // Can hold up to 19 chars + '\0'
char city[] = "New York";    // Size determined automatically

// Important: Always leave room for null terminator!
char word[6] = "Hello";      // Needs 6 spaces: H-e-l-l-o-\0

// String input (be careful with buffer overflow!)
char username[50];
cout << "Enter username: ";
cin >> username;             // Reads a single word (stops at whitespace)
// To read a whole line (including spaces) instead, use:
// cin.getline(username, 50);

// String functions (need #include <cstring>)
char str1[20] = "Hello";
char str2[20] = "World";
char str3[40];

strlen(str1);                // Returns 5
strcpy(str3, str1);         // Copies str1 to str3
strcat(str3, " ");          // Appends space
strcat(str3, str2);         // str3 now contains "Hello World"
strcmp(str1, str2);         // Compares strings

The Modern Way: C++ String Class

The string class is like having a smart container that grows and shrinks as needed!

graph TD A[C++ String Class] --> B[Dynamic Size] A --> C[Easy Operations] A --> D[Safe to Use] B --> E[Grows automatically] C --> F[+ for concatenation] D --> G[No buffer overflow] E --> H["string s = 'Hello';<br/>s += ' World';"] F --> I["string full = first + last;"] G --> J[Memory managed for you]

String Class Examples

#include <iostream>
#include <string>
using namespace std;

// Declaration and initialization
string name = "Alice";
string empty;                    // Empty string
string greeting("Hello");        // Alternative syntax

// String operations
string first = "John";
string last = "Doe";
string full = first + " " + last;  // "John Doe"

// String methods
string text = "Hello World";
cout << text.length() << '\n';     // 11
cout << text.size() << '\n';       // 11 (same as length)
cout << text[0] << '\n';           // 'H'
cout << text.at(6) << '\n';        // 'W' (with bounds checking)

// String modification
text.append("!");                   // "Hello World!"
text.insert(5, ",");               // "Hello, World!"
text.erase(5, 1);                  // Remove the comma
text.replace(0, 5, "Hi");          // "Hi World!"

// Finding substrings
size_t pos = text.find("World");   // Returns position or string::npos
if (pos != string::npos) {
    cout << "Found at position: " << pos << '\n';
}

// Substring extraction
string sub = text.substr(3, 5);    // Extract 5 chars starting at pos 3

Array Bounds and Safety

Going outside array bounds is like trying to access locker #31 when there are only 30 lockers!

Practice Exercise: Grade Management System

πŸ‹οΈ Build a Grade Tracker

Create a program that manages student grades:

  1. Store grades for 5 students
  2. Calculate each student's average
  3. Find the highest and lowest grades
  4. Display a grade report
#include <iostream>
#include <string>
using namespace std;

int main() {
    const int NUM_STUDENTS = 5;
    const int NUM_TESTS = 3;

    string names[NUM_STUDENTS];
    int grades[NUM_STUDENTS][NUM_TESTS];

    // TODO: Input student names and grades
    // TODO: Calculate averages
    // TODO: Find highest and lowest
    // TODO: Display report

    return 0;
}
βœ… Solution
// Input phase
for (int i = 0; i < NUM_STUDENTS; i++) {
    cout << "Enter name for student " << i+1 << ": ";
    cin >> names[i];

    cout << "Enter 3 test grades: ";
    for (int j = 0; j < NUM_TESTS; j++) {
        cin >> grades[i][j];
    }
}

// Calculate averages
double averages[NUM_STUDENTS];
for (int i = 0; i < NUM_STUDENTS; i++) {
    int sum = 0;
    for (int j = 0; j < NUM_TESTS; j++) {
        sum += grades[i][j];
    }
    averages[i] = static_cast<double>(sum) / NUM_TESTS;
}

Common Array Algorithms

Essential Array Algorithms Linear Search Look at each element in order Stop when found or end reached Works on any array Bubble Sort Compare adjacent elements Swap if out of order Repeat until sorted Find Min/Max Start with first element Compare with each element Update if smaller/larger found Array Reversal Swap first with last Swap second with second-last Stop at middle Shift Elements Move elements left or right Used for insertion/deletion Watch for bounds!

String Manipulation Examples

// Common string operations
string sentence = "The quick brown fox";

// Convert to uppercase (range-based for is cleaner than an index loop)
// Note: cast to unsigned char first β€” passing a negative char to toupper()
// is undefined behavior. Needs #include <cctype>.
for (char& c : sentence) {
    c = toupper(static_cast<unsigned char>(c));
}

// Count words
int wordCount = 0;
bool inWord = false;
for (int i = 0; i < sentence.length(); i++) {
    if (sentence[i] != ' ' && !inWord) {
        wordCount++;
        inWord = true;
    } else if (sentence[i] == ' ') {
        inWord = false;
    }
}

// Reverse a string
string reversed = "";
for (int i = sentence.length() - 1; i >= 0; i--) {
    reversed += sentence[i];
}

// Check if palindrome
string word = "racecar";
bool isPalindrome = true;
for (int i = 0; i < word.length() / 2; i++) {
    if (word[i] != word[word.length() - 1 - i]) {
        isPalindrome = false;
        break;
    }
}

Challenge Exercise: Text Analysis

πŸ‹οΈ Advanced String Challenge

Create a program that analyzes a sentence and reports:

  1. Number of words
  2. Number of vowels and consonants
  3. Longest word
  4. Average word length
πŸ’‘ Hint

Use isalpha() to check if a character is a letter; track word boundaries with spaces; store each word in an array or use string methods.

Arrays vs Vectors (Preview)

C++ also offers dynamic arrays called vectors - they're like arrays that can grow!

graph LR A[Fixed Arrays] --> B[Size set at compile time] A --> C[Cannot resize] A --> D[Stack memory] E[Vectors] --> F[Size can change] E --> G[Can grow/shrink] E --> H[Heap memory] B --> I["int arr[10];"] F --> J["vector⟨int⟩ v;"]

🎯 Quick Quiz

Question 1: Given the declaration int scores[5];, what is the valid range of indices for accessing elements?

Question 2: What is wrong with this declaration: char word[5] = "Hello";?

Question 3: What does text.find("World") return when "World" is not found in text?

Summary

πŸŽ‰ Key Takeaways

  • Arrays store multiple values of the same type in contiguous memory
  • Indexing starts at 0 - the first element is array[0]
  • Array size is fixed at compile time and cannot change
  • 2D arrays are arrays of arrays - perfect for grids and tables
  • C-style strings are character arrays ending with '\0'
  • String class provides safer, more flexible string handling
  • Always check bounds - accessing outside array limits causes undefined behavior
  • Use loops to process array elements efficiently
graph TD A["Master Arrays & Strings"] --> B[Store Collections] B --> C[Process Data Sets] C --> D[Build Real Applications] D --> E[Games, Databases, Analysis Tools!]

πŸ“š Additional Resources

πŸš€ What's Next?

You can now store and process whole collections of data with arrays and strings. Next, in Lesson 7: Functions, you'll learn to package logic into reusable blocks β€” including how to pass those very arrays into functions to keep your grade-tracking code organized and DRY.

πŸŽ‰ Collections conquered!

You just leveled up from single values to whole data sets β€” arrays, grids, and strings are the backbone of nearly every real program you'll write from here on.