Module 4.1

Arrays in C++

Learn C++ arrays—fixed-size collections of elements stored in contiguous memory. Master array declaration, initialization, multidimensional arrays, and working with arrays in functions.

40 min read
Intermediate
Hands-on Examples
What You'll Learn
  • Array declaration & initialization
  • Accessing & modifying elements
  • Multidimensional arrays
  • Arrays with functions
  • C-strings (character arrays)
Contents
01

Introduction to Arrays

An array is a collection of elements of the same type stored in contiguous memory locations. Arrays allow you to store multiple values under a single variable name and access them using an index.

Concept

Array

An array is a fixed-size sequential collection of elements of the same data type. Elements are stored in contiguous memory and accessed using zero-based indices.

Syntax: type arrayName[size];

#include <iostream>
using namespace std;

int main() {
    // Declare an array of 5 integers
    int numbers[5] = {10, 20, 30, 40, 50};
    
    // Memory layout (contiguous):
    // [10][20][30][40][50]
    //  0   1   2   3   4   <- indices
    
    cout << "First element: " << numbers[0] << endl;   // 10
    cout << "Third element: " << numbers[2] << endl;   // 30
    cout << "Last element: " << numbers[4] << endl;    // 50
    
    // Array size is fixed at compile time
    cout << "Array size: " << sizeof(numbers) / sizeof(numbers[0]) << endl;  // 5
    
    return 0;
}

Why Use Arrays?

Store Multiple Values

Hold many related values under one name

Fast Access

O(1) random access by index

Memory Efficient

Contiguous storage, cache-friendly

02

Array Declaration & Initialization

Arrays can be declared with or without initialization. The size must be known at compile time for static arrays. There are several ways to initialize arrays in C++.

#include <iostream>
using namespace std;

int main() {
    // Method 1: Declaration without initialization
    int arr1[5];  // Contains garbage values!
    
    // Method 2: Declaration with full initialization
    int arr2[5] = {1, 2, 3, 4, 5};
    
    // Method 3: Partial initialization (remaining elements = 0)
    int arr3[5] = {1, 2};  // {1, 2, 0, 0, 0}
    
    // Method 4: Initialize all to zero
    int arr4[5] = {0};     // {0, 0, 0, 0, 0}
    int arr5[5] = {};      // {0, 0, 0, 0, 0} (C++11)
    
    // Method 5: Size deduced from initializer
    int arr6[] = {10, 20, 30};  // Size is 3
    
    // Method 6: Uniform initialization (C++11)
    int arr7[4]{1, 2, 3, 4};
    
    // Print arr3 to show partial initialization
    cout << "arr3: ";
    for (int i = 0; i < 5; i++) {
        cout << arr3[i] << " ";
    }
    cout << endl;  // 1 2 0 0 0
    
    // Size of arr6
    cout << "arr6 size: " << sizeof(arr6) / sizeof(arr6[0]) << endl;  // 3
    
    return 0;
}

Constant Size Requirement

#include <iostream>
using namespace std;

int main() {
    // Size must be a constant expression
    const int SIZE = 10;
    int arr1[SIZE];      // OK - const
    
    constexpr int N = 5;
    int arr2[N];         // OK - constexpr
    
    int arr3[100];       // OK - literal
    
    // Variable-length arrays (VLA) - NOT standard C++!
    // int n = 5;
    // int arr4[n];      // Error in standard C++ (some compilers allow as extension)
    
    // For dynamic size, use std::vector or dynamic allocation
    int n = 5;
    int* dynamicArr = new int[n];  // Dynamic array
    // ... use array ...
    delete[] dynamicArr;  // Don't forget to free!
    
    return 0;
}

Practice Questions: Declaration

Task: Declare an array of 4 doubles with values 1.1, 2.2, 3.3, 4.4.

Show Solution
double values[4] = {1.1, 2.2, 3.3, 4.4};
// or
double values[] = {1.1, 2.2, 3.3, 4.4};

int data[6] = {5, 10, 15};
Show Solution
// data = {5, 10, 15, 0, 0, 0}
// Partial initialization fills remaining elements with 0
03

Accessing & Modifying Elements

Array elements are accessed using the subscript operator [] with zero-based indexing. The first element is at index 0, and the last element is at index size - 1.

#include <iostream>
using namespace std;

int main() {
    int scores[5] = {85, 90, 78, 92, 88};
    
    // Accessing elements (read)
    cout << "First score: " << scores[0] << endl;   // 85
    cout << "Last score: " << scores[4] << endl;    // 88
    
    // Modifying elements (write)
    scores[2] = 95;  // Change third element
    cout << "Updated third score: " << scores[2] << endl;  // 95
    
    // Using variables as index
    int index = 3;
    cout << "Score at index " << index << ": " << scores[index] << endl;
    
    // Increment an element
    scores[0]++;
    cout << "First score after increment: " << scores[0] << endl;  // 86
    
    return 0;
}
DANGER: Out-of-Bounds Access!
int arr[5] = {1, 2, 3, 4, 5};

// UNDEFINED BEHAVIOR - no bounds checking!
cout << arr[10];   // Reads garbage or crashes
arr[-1] = 100;     // Writes to invalid memory
arr[5] = 50;       // Past the end (valid indices: 0-4)

// C++ does NOT check array bounds at runtime!
// Always ensure: 0 <= index < size

Array and Pointer Relationship

#include <iostream>
using namespace std;

int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    
    // Array name decays to pointer to first element
    int* ptr = arr;  // Same as: int* ptr = &arr[0];
    
    // These are equivalent:
    cout << arr[2] << endl;       // 30 - subscript notation
    cout << *(arr + 2) << endl;   // 30 - pointer arithmetic
    cout << *(ptr + 2) << endl;   // 30 - using pointer
    cout << ptr[2] << endl;       // 30 - subscript on pointer
    
    // Address comparison
    cout << "arr = " << arr << endl;
    cout << "&arr[0] = " << &arr[0] << endl;  // Same address
    
    return 0;
}

Practice Questions: Accessing Elements

Task: Given int nums[7] = {5, 10, 15, 20, 25, 30, 35};, access the middle element.

Show Solution
int middle = nums[3];  // 20
// or using size
int size = 7;
int middle = nums[size / 2];  // nums[3] = 20

Task: Swap the first and last elements of an array of 5 integers.

Show Solution
int arr[5] = {1, 2, 3, 4, 5};
int temp = arr[0];
arr[0] = arr[4];
arr[4] = temp;
// arr is now {5, 2, 3, 4, 1}
04

Array Iteration

Loops are used to process all elements in an array. C++ offers several ways to iterate through arrays: for loops, while loops, and range-based for loops (C++11).

#include <iostream>
using namespace std;

int main() {
    int numbers[] = {10, 20, 30, 40, 50};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    
    // Method 1: Traditional for loop
    cout << "For loop: ";
    for (int i = 0; i < size; i++) {
        cout << numbers[i] << " ";
    }
    cout << endl;
    
    // Method 2: While loop
    cout << "While loop: ";
    int j = 0;
    while (j < size) {
        cout << numbers[j] << " ";
        j++;
    }
    cout << endl;
    
    // Method 3: Range-based for loop (C++11) - READ ONLY
    cout << "Range-based: ";
    for (int num : numbers) {
        cout << num << " ";
    }
    cout << endl;
    
    // Method 4: Range-based with reference - CAN MODIFY
    cout << "Doubling values: ";
    for (int& num : numbers) {
        num *= 2;  // Modifies original array
    }
    for (int num : numbers) {
        cout << num << " ";  // 20 40 60 80 100
    }
    cout << endl;
    
    return 0;
}

Common Array Operations

#include <iostream>
using namespace std;

int main() {
    int arr[] = {5, 2, 8, 1, 9, 3};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    // Find sum
    int sum = 0;
    for (int i = 0; i < size; i++) {
        sum += arr[i];
    }
    cout << "Sum: " << sum << endl;  // 28
    
    // Find average
    double avg = static_cast<double>(sum) / size;
    cout << "Average: " << avg << endl;  // 4.666...
    
    // Find maximum
    int maxVal = arr[0];
    for (int i = 1; i < size; i++) {
        if (arr[i] > maxVal) {
            maxVal = arr[i];
        }
    }
    cout << "Max: " << maxVal << endl;  // 9
    
    // Find minimum
    int minVal = arr[0];
    for (int i = 1; i < size; i++) {
        if (arr[i] < minVal) {
            minVal = arr[i];
        }
    }
    cout << "Min: " << minVal << endl;  // 1
    
    // Count occurrences
    int target = 5;
    int count = 0;
    for (int i = 0; i < size; i++) {
        if (arr[i] == target) count++;
    }
    cout << "Count of " << target << ": " << count << endl;  // 1
    
    return 0;
}

Practice Questions: Iteration

Task: Print elements of an array in reverse order.

Show Solution
int arr[] = {1, 2, 3, 4, 5};
int size = 5;

for (int i = size - 1; i >= 0; i--) {
    cout << arr[i] << " ";
}
// Output: 5 4 3 2 1

Task: Count how many even numbers are in the array {3, 8, 2, 5, 10, 7, 4}.

Show Solution
int arr[] = {3, 8, 2, 5, 10, 7, 4};
int size = 7;
int evenCount = 0;

for (int i = 0; i < size; i++) {
    if (arr[i] % 2 == 0) {
        evenCount++;
    }
}
cout << "Even numbers: " << evenCount << endl;  // 4

Task: Reverse an array in place (without using another array).

Show Solution
int arr[] = {1, 2, 3, 4, 5};
int size = 5;

for (int i = 0; i < size / 2; i++) {
    int temp = arr[i];
    arr[i] = arr[size - 1 - i];
    arr[size - 1 - i] = temp;
}
// arr is now {5, 4, 3, 2, 1}
05

Multidimensional Arrays

Multidimensional arrays are arrays of arrays. The most common is the 2D array (matrix), but C++ supports arrays with any number of dimensions.

#include <iostream>
using namespace std;

int main() {
    // 2D Array Declaration: type name[rows][cols]
    int matrix[3][4] = {
        {1, 2, 3, 4},      // Row 0
        {5, 6, 7, 8},      // Row 1
        {9, 10, 11, 12}    // Row 2
    };
    
    // Accessing elements: matrix[row][col]
    cout << "Element at [1][2]: " << matrix[1][2] << endl;  // 7
    
    // Modifying elements
    matrix[0][0] = 100;
    
    // Print entire matrix
    cout << "Matrix:" << endl;
    for (int i = 0; i < 3; i++) {           // rows
        for (int j = 0; j < 4; j++) {       // columns
            cout << matrix[i][j] << "\t";
        }
        cout << endl;
    }
    
    return 0;
}

2D Array Initialization

#include <iostream>
using namespace std;

int main() {
    // Method 1: Full initialization
    int a[2][3] = {{1, 2, 3}, {4, 5, 6}};
    
    // Method 2: Flat initialization (fills row by row)
    int b[2][3] = {1, 2, 3, 4, 5, 6};  // Same as above
    
    // Method 3: Partial initialization
    int c[2][3] = {{1}, {4}};  // {{1,0,0}, {4,0,0}}
    
    // Method 4: All zeros
    int d[2][3] = {};  // All elements = 0
    
    // First dimension can be omitted
    int e[][3] = {{1, 2, 3}, {4, 5, 6}};  // 2 rows inferred
    
    // Print c to show partial init
    cout << "Array c:" << endl;
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
            cout << c[i][j] << " ";
        }
        cout << endl;
    }
    // Output:
    // 1 0 0
    // 4 0 0
    
    return 0;
}

3D Arrays and Beyond

#include <iostream>
using namespace std;

int main() {
    // 3D Array: think of it as multiple 2D matrices
    int cube[2][3][4];  // 2 matrices, each 3x4
    
    // Initialize
    int value = 0;
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 3; j++) {
            for (int k = 0; k < 4; k++) {
                cube[i][j][k] = value++;
            }
        }
    }
    
    // Access
    cout << "cube[1][2][3] = " << cube[1][2][3] << endl;  // 23
    
    // Total elements: 2 * 3 * 4 = 24
    cout << "Total size: " << sizeof(cube) / sizeof(int) << endl;  // 24
    
    return 0;
}

Practice Questions: Multidimensional Arrays

Task: Calculate the sum of all elements in a 3x3 matrix.

Show Solution
int matrix[3][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

int sum = 0;
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        sum += matrix[i][j];
    }
}
cout << "Sum: " << sum << endl;  // 45

Task: Transpose a 3x3 matrix (swap rows and columns).

Show Solution
int matrix[3][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

// Transpose in place (for square matrix)
for (int i = 0; i < 3; i++) {
    for (int j = i + 1; j < 3; j++) {
        int temp = matrix[i][j];
        matrix[i][j] = matrix[j][i];
        matrix[j][i] = temp;
    }
}
// Result:
// 1 4 7
// 2 5 8
// 3 6 9
06

Arrays & Functions

When passing arrays to functions, they decay to pointers. This means functions receive the memory address, not a copy—changes affect the original array. You must pass the size separately.

#include <iostream>
using namespace std;

// Array parameter (decays to pointer)
// These are equivalent:
void printArray1(int arr[], int size);
void printArray2(int* arr, int size);

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;
}

// Modifying array (changes reflect in original)
void doubleElements(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        arr[i] *= 2;
    }
}

// Prevent modification with const
void printOnly(const int arr[], int size) {
    for (int i = 0; i < size; i++) {
        cout << arr[i] << " ";
        // arr[i] = 0;  // Error! Cannot modify const
    }
    cout << endl;
}

int main() {
    int numbers[] = {1, 2, 3, 4, 5};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    
    cout << "Original: ";
    printArray(numbers, size);  // 1 2 3 4 5
    
    doubleElements(numbers, size);
    
    cout << "After doubling: ";
    printArray(numbers, size);  // 2 4 6 8 10
    
    return 0;
}

Passing 2D Arrays

#include <iostream>
using namespace std;

// For 2D arrays, column size must be specified
void print2D(int arr[][4], int rows) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < 4; j++) {
            cout << arr[i][j] << " ";
        }
        cout << endl;
    }
}

// Using pointer notation
void print2DPtr(int (*arr)[4], int rows) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < 4; j++) {
            cout << arr[i][j] << " ";
        }
        cout << endl;
    }
}

int main() {
    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    
    print2D(matrix, 3);
    
    return 0;
}

Returning Arrays from Functions

#include <iostream>
using namespace std;

// Cannot return local array - use dynamic allocation
int* createArray(int size) {
    int* arr = new int[size];
    for (int i = 0; i < size; i++) {
        arr[i] = i * 10;
    }
    return arr;  // Return pointer to heap memory
}

// Or use output parameter
void fillArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        arr[i] = i * 10;
    }
}

int main() {
    // Method 1: Dynamic allocation
    int* dynamicArr = createArray(5);
    for (int i = 0; i < 5; i++) {
        cout << dynamicArr[i] << " ";  // 0 10 20 30 40
    }
    cout << endl;
    delete[] dynamicArr;  // Don't forget!
    
    // Method 2: Output parameter
    int staticArr[5];
    fillArray(staticArr, 5);
    for (int i = 0; i < 5; i++) {
        cout << staticArr[i] << " ";  // 0 10 20 30 40
    }
    cout << endl;
    
    return 0;
}

Practice Questions: Arrays & Functions

Task: Write a function that takes an integer array and its size, and returns the maximum value.

Show Solution
int findMax(const int arr[], int size) {
    int maxVal = arr[0];
    for (int i = 1; i < size; i++) {
        if (arr[i] > maxVal) {
            maxVal = arr[i];
        }
    }
    return maxVal;
}

// Usage:
int nums[] = {3, 7, 2, 9, 1};
cout << findMax(nums, 5) << endl;  // 9
07

Array of Pointers

An array of pointers is an array where each element is a pointer. This is useful for storing addresses of variables, creating dynamic 2D arrays, and managing collections of strings.

#include <iostream>
using namespace std;

int main() {
    // Array of pointers to int
    int a = 10, b = 20, c = 30;
    int* ptrArr[3];  // Array of 3 int pointers
    
    ptrArr[0] = &a;
    ptrArr[1] = &b;
    ptrArr[2] = &c;
    
    // Access values through pointer array
    for (int i = 0; i < 3; i++) {
        cout << "ptrArr[" << i << "] points to: " << *ptrArr[i] << endl;
    }
    // Output:
    // ptrArr[0] points to: 10
    // ptrArr[1] points to: 20
    // ptrArr[2] points to: 30
    
    // Modify through pointer array
    *ptrArr[1] = 200;
    cout << "b after modification: " << b << endl;  // 200
    
    return 0;
}

Array of Pointers vs Pointer to Array

#include <iostream>
using namespace std;

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    
    // POINTER TO ARRAY: A single pointer to an array of 5 ints
    int (*ptrToArr)[5] = &arr;
    cout << "Pointer to array:" << endl;
    cout << "(*ptrToArr)[0] = " << (*ptrToArr)[0] << endl;  // 1
    cout << "(*ptrToArr)[4] = " << (*ptrToArr)[4] << endl;  // 5
    
    // ARRAY OF POINTERS: An array containing 5 pointers
    int* arrOfPtr[5];
    for (int i = 0; i < 5; i++) {
        arrOfPtr[i] = &arr[i];  // Each pointer points to an element
    }
    cout << "\nArray of pointers:" << endl;
    for (int i = 0; i < 5; i++) {
        cout << "*arrOfPtr[" << i << "] = " << *arrOfPtr[i] << endl;
    }
    
    // Key difference:
    // int (*ptr)[5]  -> ONE pointer to an array of 5 ints
    // int* ptr[5]    -> FIVE pointers to ints
    
    return 0;
}

Dynamic 2D Array Using Pointer Array

#include <iostream>
using namespace std;

int main() {
    int rows = 3, cols = 4;
    
    // Create array of pointers (one pointer per row)
    int** matrix = new int*[rows];
    
    // Allocate each row
    for (int i = 0; i < rows; i++) {
        matrix[i] = new int[cols];
    }
    
    // Initialize
    int value = 1;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = value++;
        }
    }
    
    // Print
    cout << "Dynamic 2D array:" << endl;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            cout << matrix[i][j] << "\t";
        }
        cout << endl;
    }
    
    // Free memory (reverse order)
    for (int i = 0; i < rows; i++) {
        delete[] matrix[i];  // Delete each row
    }
    delete[] matrix;  // Delete array of pointers
    
    return 0;
}

Array of C-Strings (char* array)

#include <iostream>
using namespace std;

int main() {
    // Array of pointers to char (C-strings)
    const char* fruits[] = {
        "Apple",
        "Banana",
        "Cherry",
        "Date"
    };
    
    int count = sizeof(fruits) / sizeof(fruits[0]);
    
    cout << "Fruits:" << endl;
    for (int i = 0; i < count; i++) {
        cout << i + 1 << ". " << fruits[i] << endl;
    }
    
    // Each element is a pointer to first char of string literal
    cout << "\nFirst char of each:" << endl;
    for (int i = 0; i < count; i++) {
        cout << fruits[i][0] << endl;  // A, B, C, D
    }
    
    // Compare with 2D char array:
    // char fruits2D[4][10] = {"Apple", "Banana", ...};
    // Fixed size per string, wastes memory for short strings
    
    return 0;
}

Command Line Arguments

#include <iostream>
using namespace std;

// main() receives command line args as array of pointers
int main(int argc, char* argv[]) {
    // argc = argument count
    // argv = array of C-strings (char pointers)
    
    cout << "Number of arguments: " << argc << endl;
    
    for (int i = 0; i < argc; i++) {
        cout << "argv[" << i << "] = " << argv[i] << endl;
    }
    
    // Example run: ./program hello world
    // Output:
    // Number of arguments: 3
    // argv[0] = ./program
    // argv[1] = hello
    // argv[2] = world
    
    return 0;
}

Practice Questions: Array of Pointers

Task: Create 3 integer variables and an array of pointers. Store the addresses and print values using the pointer array.

Show Solution
int x = 100, y = 200, z = 300;
int* ptrs[3] = {&x, &y, &z};

for (int i = 0; i < 3; i++) {
    cout << *ptrs[i] << " ";  // 100 200 300
}

Task: Create a 2x3 dynamic 2D array, fill it with values 1-6, print it, and properly deallocate.

Show Solution
int** arr = new int*[2];
for (int i = 0; i < 2; i++) {
    arr[i] = new int[3];
}

int val = 1;
for (int i = 0; i < 2; i++) {
    for (int j = 0; j < 3; j++) {
        arr[i][j] = val++;
        cout << arr[i][j] << " ";
    }
    cout << endl;
}
// Output: 1 2 3
//         4 5 6

for (int i = 0; i < 2; i++) delete[] arr[i];
delete[] arr;
08

C-Strings (Character Arrays)

C-strings are character arrays terminated by a null character ('\0'). They are the traditional way to handle strings in C and remain important in C++ for compatibility and low-level operations.

#include <iostream>
#include <cstring>  // C string functions
using namespace std;

int main() {
    // C-string declaration
    char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
    
    // Easier: string literal (auto adds '\0')
    char message[] = "Hello";  // Size is 6 (5 chars + '\0')
    
    // Print C-string
    cout << greeting << endl;  // Hello
    cout << message << endl;   // Hello
    
    // Individual characters
    cout << "First char: " << greeting[0] << endl;  // H
    
    // Length (not including '\0')
    cout << "Length: " << strlen(message) << endl;  // 5
    
    // Modifying
    message[0] = 'J';
    cout << message << endl;  // Jello
    
    return 0;
}

Common C-String Functions

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

int main() {
    char str1[20] = "Hello";
    char str2[20] = "World";
    char str3[20];
    
    // strlen - length (excludes '\0')
    cout << "Length of str1: " << strlen(str1) << endl;  // 5
    
    // strcpy - copy string
    strcpy(str3, str1);
    cout << "str3 after strcpy: " << str3 << endl;  // Hello
    
    // strcat - concatenate
    strcat(str1, " ");
    strcat(str1, str2);
    cout << "str1 after strcat: " << str1 << endl;  // Hello World
    
    // strcmp - compare (0 if equal)
    if (strcmp(str2, "World") == 0) {
        cout << "str2 equals 'World'" << endl;
    }
    
    // strchr - find character
    char* pos = strchr(str1, 'o');
    if (pos != nullptr) {
        cout << "Found 'o' at position: " << (pos - str1) << endl;  // 4
    }
    
    // strstr - find substring
    pos = strstr(str1, "World");
    if (pos != nullptr) {
        cout << "Found 'World' at position: " << (pos - str1) << endl;  // 6
    }
    
    return 0;
}
C-String Pitfalls
// Buffer overflow - no bounds checking!
char small[5];
strcpy(small, "This is way too long!");  // DANGER!

// Forgetting null terminator
char bad[5] = {'H', 'e', 'l', 'l', 'o'};  // No '\0'!
cout << bad;  // Undefined behavior - reads past array

// Prefer std::string in modern C++ for safety!

Practice Questions: C-Strings

Task: Write code to count vowels in a C-string.

Show Solution
char str[] = "Hello World";
int vowels = 0;

for (int i = 0; str[i] != '\0'; i++) {
    char c = tolower(str[i]);
    if (c == 'a' || c == 'e' || c == 'i' || 
        c == 'o' || c == 'u') {
        vowels++;
    }
}
cout << "Vowels: " << vowels << endl;  // 3
09

std::array (C++11)

C++11 introduced std::array, a container that encapsulates fixed-size arrays. It provides bounds checking (with .at()), knows its size, and works with STL algorithms.

#include <iostream>
#include <array>
#include <algorithm>
using namespace std;

int main() {
    // Declaration: std::array<type, size>
    array<int, 5> arr = {10, 20, 30, 40, 50};
    
    // Size is part of the type!
    cout << "Size: " << arr.size() << endl;  // 5
    
    // Access with [] (no bounds check)
    cout << "arr[0] = " << arr[0] << endl;
    
    // Access with .at() (bounds checked - throws exception)
    cout << "arr.at(2) = " << arr.at(2) << endl;
    
    // First and last
    cout << "Front: " << arr.front() << endl;  // 10
    cout << "Back: " << arr.back() << endl;    // 50
    
    // Range-based for loop
    for (int val : arr) {
        cout << val << " ";
    }
    cout << endl;
    
    // Works with STL algorithms
    sort(arr.begin(), arr.end(), greater<int>());  // Descending
    cout << "Sorted descending: ";
    for (int val : arr) {
        cout << val << " ";  // 50 40 30 20 10
    }
    cout << endl;
    
    // Fill with a value
    array<int, 5> zeros;
    zeros.fill(0);
    
    return 0;
}

std::array vs C-style Arrays

Feature C-style Array std::array
Size sizeof() / sizeof(element) .size()
Bounds Check No .at() throws
Pass to Function Decays to pointer Passes as object
Assignment Not allowed Allowed
STL Compatible Limited Full
#include <iostream>
#include <array>
using namespace std;

// std::array can be passed and returned properly
array<int, 5> createArray() {
    return {1, 2, 3, 4, 5};  // Returns copy of array
}

void printArray(const array<int, 5>& arr) {
    for (int val : arr) {
        cout << val << " ";
    }
    cout << endl;
}

int main() {
    array<int, 5> arr1 = createArray();
    printArray(arr1);  // 1 2 3 4 5
    
    // Array assignment works!
    array<int, 5> arr2;
    arr2 = arr1;  // Copies all elements
    
    // Comparison works!
    if (arr1 == arr2) {
        cout << "Arrays are equal" << endl;
    }
    
    return 0;
}

Key Takeaways

Fixed Size

Array size must be known at compile time

Zero-Based Index

First element at index 0, last at size-1

No Bounds Check

C-style arrays don't check boundaries

Decay to Pointer

Arrays passed to functions become pointers

Multidimensional

2D arrays use [row][col] notation

Prefer std::array

Use std::array for safety and features

Knowledge Check

Quick Quiz

Test what you have learned about C++ arrays

1 What is the index of the last element in int arr[10]?
2 What values does int arr[4] = {1, 2}; contain?
3 When an array is passed to a function, what happens?
4 How do you access element at row 2, column 3 in a 2D array?
5 What terminates a C-string?
6 What advantage does std::array have over C-style arrays?
Answer all questions to check your score