C++ Arrays: Complete Guide to 1D and 2D Arrays
Master C++ arrays with comprehensive examples of 1D arrays, 2D arrays, operations, memory representation, and practical applications. Learn efficient array manipulation techniques.
1D Arrays
Linear data structures
2D Arrays
Matrix/tabular data
Memory Layout
Contiguous storage
Operations
Traversal, search, sort
Understanding Arrays in C++
Arrays are fundamental data structures in C++ that store a fixed-size sequential collection of elements of the same type. They provide efficient access to elements using indices and are stored in contiguous memory locations.
1D Array Linear Structure
Single row of elements accessed by a single index. Perfect for lists and sequences.
2D Array Tabular Structure
Rows and columns matrix accessed by two indices. Ideal for grids and tables.
Contiguous Memory
Elements stored sequentially in memory for fast access via pointer arithmetic.
Fixed Size
Size must be known at compile time (unless using dynamic arrays).
Key Concepts:
- Fixed Size: Array size cannot change after declaration
- Homogeneous: All elements must be same data type
- Zero-based Indexing: First element is at index 0
- Contiguous Memory: Elements stored consecutively
- Random Access: Direct access to any element via index
1. One-Dimensional (1D) Arrays
data_type array_name[size];
// Examples:
int numbers[5]; // Declare array of 5 integers
float prices[10]; // Declare array of 10 floats
char name[20]; // Declare array of 20 characters
Declaration and Initialization
#include <iostream>
using namespace std;
int main() {
// Method 1: Declaration then initialization
int numbers[5]; // Declaration
numbers[0] = 10; // Initialization
numbers[1] = 20;
numbers[2] = 30;
numbers[3] = 40;
numbers[4] = 50;
// Method 2: Declaration with initialization
int primes[] = {2, 3, 5, 7, 11, 13, 17}; // Size automatically calculated
// Method 3: Partial initialization (rest are 0)
int scores[10] = {95, 88, 76}; // scores[0]=95, scores[1]=88, scores[2]=76, rest=0
// Method 4: All elements initialized to 0
int zeros[10] = {0}; // All 10 elements set to 0
int allZeros[10] = {}; // Also all 10 elements set to 0 (C++11)
// Method 5: Using loop for initialization
int squares[5];
for(int i = 0; i < 5; i++) {
squares[i] = (i+1) * (i+1); // 1, 4, 9, 16, 25
}
// Method 6: Character array (string)
char vowels[] = {'a', 'e', 'i', 'o', 'u'};
char name[] = "John"; // Automatically adds null terminator '\0'
// Display array contents
cout << "Numbers array: ";
for(int i = 0; i < 5; i++) {
cout << numbers[i] << " ";
}
cout << endl;
cout << "Primes array: ";
for(int i = 0; i < 7; i++) {
cout << primes[i] << " ";
}
cout << endl;
cout << "Squares array: ";
for(int i = 0; i < 5; i++) {
cout << squares[i] << " ";
}
cout << endl;
cout << "Vowels: ";
for(int i = 0; i < 5; i++) {
cout << vowels[i] << " ";
}
cout << endl;
cout << "Name: " << name << endl;
return 0;
}
Memory Visualization
Memory Layout of int arr[5] = {10, 20, 30, 40, 50}
Contiguous memory addresses: &arr[0], &arr[1], &arr[2], &arr[3], &arr[4]
Common Operations on 1D Arrays
#include <iostream>
#include <algorithm> // For sort()
using namespace std;
int main() {
const int SIZE = 8;
int arr[SIZE] = {45, 12, 67, 23, 89, 34, 56, 78};
cout << "Original array: ";
for(int i = 0; i < SIZE; i++) {
cout << arr[i] << " ";
}
cout << endl;
// 1. Find maximum element
int max = arr[0];
for(int i = 1; i < SIZE; i++) {
if(arr[i] > max) {
max = arr[i];
}
}
cout << "Maximum element: " << max << endl;
// 2. Find minimum element
int min = arr[0];
for(int i = 1; i < SIZE; i++) {
if(arr[i] < min) {
min = arr[i];
}
}
cout << "Minimum element: " << min << endl;
// 3. Calculate sum
int sum = 0;
for(int i = 0; i < SIZE; i++) {
sum += arr[i];
}
cout << "Sum of elements: " << sum << endl;
cout << "Average: " << (double)sum / SIZE << endl;
// 4. Linear search
int target = 56;
bool found = false;
int position = -1;
for(int i = 0; i < SIZE; i++) {
if(arr[i] == target) {
found = true;
position = i;
break;
}
}
if(found) {
cout << target << " found at index " << position << endl;
} else {
cout << target << " not found in array" << endl;
}
// 5. Reverse array
cout << "Array in reverse: ";
for(int i = SIZE - 1; i >= 0; i--) {
cout << arr[i] << " ";
}
cout << endl;
// 6. Sort array (using std::sort)
int sortedArr[SIZE];
copy(arr, arr + SIZE, sortedArr); // Copy original array
sort(sortedArr, sortedArr + SIZE);
cout << "Sorted array (ascending): ";
for(int i = 0; i < SIZE; i++) {
cout << sortedArr[i] << " ";
}
cout << endl;
// 7. Copy array
int copyArr[SIZE];
for(int i = 0; i < SIZE; i++) {
copyArr[i] = arr[i];
}
cout << "Copied array: ";
for(int i = 0; i < SIZE; i++) {
cout << copyArr[i] << " ";
}
cout << endl;
// 8. Count even and odd numbers
int evenCount = 0, oddCount = 0;
for(int i = 0; i < SIZE; i++) {
if(arr[i] % 2 == 0) {
evenCount++;
} else {
oddCount++;
}
}
cout << "Even numbers: " << evenCount << ", Odd numbers: " << oddCount << endl;
return 0;
}
2. Two-Dimensional (2D) Arrays
data_type array_name[rows][columns];
// Examples:
int matrix[3][4]; // 3 rows, 4 columns matrix
float temperatures[7][24]; // 7 days, 24 hours
char tictactoe[3][3]; // 3x3 Tic-Tac-Toe board
Declaration and Initialization
#include <iostream>
using namespace std;
int main() {
// Method 1: Direct initialization
int matrix1[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
// Method 2: Row-major initialization (less readable)
int matrix2[2][3] = {1, 2, 3, 4, 5, 6};
// Method 3: Partial initialization
int matrix3[3][3] = {
{1, 2}, // Row 0: 1, 2, 0
{4, 5, 6}, // Row 1: 4, 5, 6
{7} // Row 2: 7, 0, 0
};
// Method 4: All zeros
int zeros[4][4] = {0};
// Method 5: Using loops for initialization
int multiplicationTable[10][10];
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 10; j++) {
multiplicationTable[i][j] = (i+1) * (j+1);
}
}
// Method 6: Character 2D array (array of strings)
char names[][20] = {
"Alice",
"Bob",
"Charlie",
"Diana"
};
// Display 2D arrays
cout << "Matrix 1 (2x3):" << endl;
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 3; j++) {
cout << matrix1[i][j] << " ";
}
cout << endl;
}
cout << "\nMultiplication Table (10x10) - First 5x5:" << endl;
for(int i = 0; i < 5; i++) {
for(int j = 0; j < 5; j++) {
cout << multiplicationTable[i][j] << "\t";
}
cout << endl;
}
cout << "\nNames array:" << endl;
for(int i = 0; i < 4; i++) {
cout << "Name " << i << ": " << names[i] << endl;
}
return 0;
}
Memory Visualization of 2D Arrays
Memory Layout of int arr[3][4]
Row-major order: Elements stored row by row in contiguous memory
Common Operations on 2D Arrays
#include <iostream>
#include <iomanip>
using namespace std;
const int ROWS = 3;
const int COLS = 3;
void displayMatrix(int matrix[ROWS][COLS], string name) {
cout << "\n" << name << ":" << endl;
for(int i = 0; i < ROWS; i++) {
for(int j = 0; j < COLS; j++) {
cout << setw(4) << matrix[i][j] << " ";
}
cout << endl;
}
}
int main() {
int A[ROWS][COLS] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int B[ROWS][COLS] = {
{9, 8, 7},
{6, 5, 4},
{3, 2, 1}
};
displayMatrix(A, "Matrix A");
displayMatrix(B, "Matrix B");
// 1. Matrix Addition
int C[ROWS][COLS]; // Result matrix
cout << "\n1. Matrix Addition (A + B):" << endl;
for(int i = 0; i < ROWS; i++) {
for(int j = 0; j < COLS; j++) {
C[i][j] = A[i][j] + B[i][j];
cout << setw(4) << C[i][j] << " ";
}
cout << endl;
}
// 2. Matrix Subtraction
cout << "\n2. Matrix Subtraction (A - B):" << endl;
for(int i = 0; i < ROWS; i++) {
for(int j = 0; j < COLS; j++) {
C[i][j] = A[i][j] - B[i][j];
cout << setw(4) << C[i][j] << " ";
}
cout << endl;
}
// 3. Matrix Transpose
cout << "\n3. Transpose of Matrix A:" << endl;
for(int i = 0; i < COLS; i++) {
for(int j = 0; j < ROWS; j++) {
cout << setw(4) << A[j][i] << " ";
}
cout << endl;
}
// 4. Find row sums
cout << "\n4. Row sums of Matrix A:" << endl;
for(int i = 0; i < ROWS; i++) {
int rowSum = 0;
for(int j = 0; j < COLS; j++) {
rowSum += A[i][j];
}
cout << "Row " << i << " sum: " << rowSum << endl;
}
// 5. Find column sums
cout << "\n5. Column sums of Matrix A:" << endl;
for(int j = 0; j < COLS; j++) {
int colSum = 0;
for(int i = 0; i < ROWS; i++) {
colSum += A[i][j];
}
cout << "Column " << j << " sum: " << colSum << endl;
}
// 6. Find diagonal elements (square matrix only)
cout << "\n6. Diagonal elements of Matrix A:" << endl;
cout << "Main diagonal: ";
for(int i = 0; i < ROWS; i++) {
cout << A[i][i] << " ";
}
cout << "\nAnti-diagonal: ";
for(int i = 0; i < ROWS; i++) {
cout << A[i][COLS-1-i] << " ";
}
cout << endl;
// 7. Search for an element
int target = 5;
bool found = false;
int foundRow = -1, foundCol = -1;
for(int i = 0; i < ROWS; i++) {
for(int j = 0; j < COLS; j++) {
if(A[i][j] == target) {
found = true;
foundRow = i;
foundCol = j;
break;
}
}
if(found) break;
}
if(found) {
cout << "\n7. Element " << target << " found at position ["
<< foundRow << "][" << foundCol << "]" << endl;
} else {
cout << "\n7. Element " << target << " not found" << endl;
}
// 8. Find maximum and minimum
int max = A[0][0], min = A[0][0];
for(int i = 0; i < ROWS; i++) {
for(int j = 0; j < COLS; j++) {
if(A[i][j] > max) max = A[i][j];
if(A[i][j] < min) min = A[i][j];
}
}
cout << "\n8. Maximum: " << max << ", Minimum: " << min << endl;
return 0;
}
3. Practical Applications
Student Marks Management System
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
const int MAX_STUDENTS = 100;
const int MAX_SUBJECTS = 5;
int main() {
string names[MAX_STUDENTS];
int marks[MAX_STUDENTS][MAX_SUBJECTS];
float averages[MAX_STUDENTS];
char grades[MAX_STUDENTS];
int numStudents;
cout << "╔═══════════════════════════════════════════╗\n";
cout << "║ STUDENT MARKS MANAGEMENT SYSTEM ║\n";
cout << "╚═══════════════════════════════════════════╝\n\n";
// Input number of students
cout << "Enter number of students (max " << MAX_STUDENTS << "): ";
cin >> numStudents;
if(numStudents > MAX_STUDENTS || numStudents <= 0) {
cout << "Invalid number of students!" << endl;
return 1;
}
// Input student data
for(int i = 0; i < numStudents; i++) {
cout << "\n═══════════════════════════════════════════\n";
cout << "Enter details for Student " << (i+1) << ":\n";
cout << "Name: ";
cin.ignore();
getline(cin, names[i]);
cout << "Enter marks for " << MAX_SUBJECTS << " subjects (0-100):\n";
int total = 0;
for(int j = 0; j < MAX_SUBJECTS; j++) {
cout << " Subject " << (j+1) << ": ";
cin >> marks[i][j];
// Validate marks
while(marks[i][j] < 0 || marks[i][j] > 100) {
cout << " Invalid marks! Enter between 0-100: ";
cin >> marks[i][j];
}
total += marks[i][j];
}
// Calculate average
averages[i] = (float)total / MAX_SUBJECTS;
// Determine grade
if(averages[i] >= 90) grades[i] = 'A';
else if(averages[i] >= 80) grades[i] = 'B';
else if(averages[i] >= 70) grades[i] = 'C';
else if(averages[i] >= 60) grades[i] = 'D';
else if(averages[i] >= 40) grades[i] = 'E';
else grades[i] = 'F';
}
// Display results
cout << "\n\n╔══════════════════════════════════════════════════════════════════════╗\n";
cout << "║ STUDENT REPORT ║\n";
cout << "╚══════════════════════════════════════════════════════════════════════╝\n\n";
cout << left << setw(25) << "Name";
for(int j = 0; j < MAX_SUBJECTS; j++) {
cout << setw(10) << ("Sub" + to_string(j+1));
}
cout << setw(10) << "Average" << setw(8) << "Grade" << endl;
cout << string(25 + MAX_SUBJECTS*10 + 18, '-') << endl;
for(int i = 0; i < numStudents; i++) {
cout << left << setw(25) << names[i];
for(int j = 0; j < MAX_SUBJECTS; j++) {
cout << setw(10) << marks[i][j];
}
cout << fixed << setprecision(2);
cout << setw(10) << averages[i];
cout << setw(8) << grades[i];
cout << endl;
}
// Calculate class statistics
float classAverage = 0;
int gradeCount[6] = {0}; // A, B, C, D, E, F
for(int i = 0; i < numStudents; i++) {
classAverage += averages[i];
switch(grades[i]) {
case 'A': gradeCount[0]++; break;
case 'B': gradeCount[1]++; break;
case 'C': gradeCount[2]++; break;
case 'D': gradeCount[3]++; break;
case 'E': gradeCount[4]++; break;
case 'F': gradeCount[5]++; break;
}
}
classAverage /= numStudents;
cout << "\n═══════════════════════════════════════════\n";
cout << "CLASS STATISTICS:\n";
cout << "═══════════════════════════════════════════\n";
cout << "Class Average: " << fixed << setprecision(2) << classAverage << "%\n";
cout << "Grade Distribution:\n";
cout << " A: " << gradeCount[0] << " students\n";
cout << " B: " << gradeCount[1] << " students\n";
cout << " C: " << gradeCount[2] << " students\n";
cout << " D: " << gradeCount[3] << " students\n";
cout << " E: " << gradeCount[4] << " students\n";
cout << " F: " << gradeCount[5] << " students\n";
// Find top student
int topIndex = 0;
for(int i = 1; i < numStudents; i++) {
if(averages[i] > averages[topIndex]) {
topIndex = i;
}
}
cout << "\nTop Performer: " << names[topIndex]
<< " with average " << averages[topIndex] << "% (Grade "
<< grades[topIndex] << ")\n";
return 0;
}
Tic-Tac-Toe Game
#include <iostream>
using namespace std;
const int SIZE = 3;
char board[SIZE][SIZE];
char currentPlayer = 'X';
void initializeBoard() {
for(int i = 0; i < SIZE; i++) {
for(int j = 0; j < SIZE; j++) {
board[i][j] = ' ';
}
}
}
void displayBoard() {
cout << "\nCurrent Board:\n\n";
for(int i = 0; i < SIZE; i++) {
for(int j = 0; j < SIZE; j++) {
cout << " " << board[i][j] << " ";
if(j < SIZE - 1) cout << "|";
}
cout << endl;
if(i < SIZE - 1) {
cout << "---+---+---\n";
}
}
cout << endl;
}
bool isValidMove(int row, int col) {
return (row >= 0 && row < SIZE && col >= 0 && col < SIZE && board[row][col] == ' ');
}
bool checkWin(char player) {
// Check rows
for(int i = 0; i < SIZE; i++) {
if(board[i][0] == player && board[i][1] == player && board[i][2] == player)
return true;
}
// Check columns
for(int j = 0; j < SIZE; j++) {
if(board[0][j] == player && board[1][j] == player && board[2][j] == player)
return true;
}
// Check diagonals
if(board[0][0] == player && board[1][1] == player && board[2][2] == player)
return true;
if(board[0][2] == player && board[1][1] == player && board[2][0] == player)
return true;
return false;
}
bool isBoardFull() {
for(int i = 0; i < SIZE; i++) {
for(int j = 0; j < SIZE; j++) {
if(board[i][j] == ' ') return false;
}
}
return true;
}
int main() {
cout << "╔═══════════════════════════════╗\n";
cout << "║ TIC-TAC-TOE GAME ║\n";
cout << "╚═══════════════════════════════╝\n\n";
cout << "Player 1: X\n";
cout << "Player 2: O\n\n";
cout << "Enter moves as row and column (0-2)\n";
initializeBoard();
displayBoard();
int row, col;
int moves = 0;
while(true) {
cout << "Player " << currentPlayer << "'s turn\n";
// Get valid move
while(true) {
cout << "Enter row (0-2): ";
cin >> row;
cout << "Enter column (0-2): ";
cin >> col;
if(isValidMove(row, col)) {
board[row][col] = currentPlayer;
break;
} else {
cout << "Invalid move! Try again.\n";
}
}
moves++;
displayBoard();
// Check for win
if(checkWin(currentPlayer)) {
cout << "Player " << currentPlayer << " wins! 🎉\n";
break;
}
// Check for draw
if(isBoardFull()) {
cout << "It's a draw! 🤝\n";
break;
}
// Switch player
currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
}
cout << "\nGame Over! Total moves: " << moves << endl;
return 0;
}
4. Memory Management & Advanced Concepts
Array Pointers and Memory Addresses
#include <iostream>
using namespace std;
int main() {
int arr[5] = {10, 20, 30, 40, 50};
cout << "Array elements and their addresses:\n";
cout << "===================================\n";
// Display elements using array indexing
for(int i = 0; i < 5; i++) {
cout << "arr[" << i << "] = " << arr[i];
cout << " Address: " << &arr[i];
cout << " Pointer arithmetic: *(arr + " << i << ") = " << *(arr + i);
cout << endl;
}
cout << "\nImportant pointer concepts:\n";
cout << "===========================\n";
// Array name as pointer
cout << "arr = " << arr << " (address of first element)\n";
cout << "&arr[0] = " << &arr[0] << " (same as arr)\n";
cout << "*arr = " << *arr << " (value at first element)\n";
// Pointer arithmetic
int *ptr = arr; // Pointer to first element
cout << "\nPointer arithmetic:\n";
cout << "ptr = " << ptr << " points to " << *ptr << endl;
cout << "ptr + 1 = " << ptr + 1 << " points to " << *(ptr + 1) << endl;
cout << "ptr + 2 = " << ptr + 2 << " points to " << *(ptr + 2) << endl;
// Array size using sizeof
cout << "\nMemory calculations:\n";
cout << "sizeof(arr) = " << sizeof(arr) << " bytes (total array size)\n";
cout << "sizeof(arr[0]) = " << sizeof(arr[0]) << " bytes (one element)\n";
cout << "Number of elements = sizeof(arr)/sizeof(arr[0]) = "
<< sizeof(arr)/sizeof(arr[0]) << endl;
// 2D array memory layout
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
cout << "\n2D Array Memory Layout:\n";
cout << "=======================\n";
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 3; j++) {
cout << "matrix[" << i << "][" << j << "] = " << matrix[i][j];
cout << " Address: " << &matrix[i][j] << endl;
}
}
cout << "\nNotice: Memory addresses are contiguous!\n";
cout << "Difference between addresses: "
<< (long)&matrix[0][1] - (long)&matrix[0][0]
<< " bytes (size of int)\n";
return 0;
}
Passing Arrays to Functions
#include <iostream>
using namespace std;
// Function to print 1D array
void printArray(int arr[], int size) {
cout << "Array elements: ";
for(int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
}
// Function to modify array (arrays are passed by reference)
void doubleArray(int arr[], int size) {
for(int i = 0; i < size; i++) {
arr[i] *= 2;
}
}
// Function to find sum of array
int arraySum(int arr[], int size) {
int sum = 0;
for(int i = 0; i < size; i++) {
sum += arr[i];
}
return sum;
}
// Function to print 2D array
void printMatrix(int matrix[][3], int rows) {
cout << "\nMatrix (" << rows << "x3):\n";
for(int i = 0; i < rows; i++) {
for(int j = 0; j < 3; j++) {
cout << matrix[i][j] << " ";
}
cout << endl;
}
}
// Function to transpose matrix
void transposeMatrix(int matrix[][3], int rows, int result[][3]) {
for(int i = 0; i < rows; i++) {
for(int j = 0; j < 3; j++) {
result[j][i] = matrix[i][j];
}
}
}
int main() {
// 1D Array operations
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers)/sizeof(numbers[0]);
cout << "1D Array Operations:\n";
cout << "====================\n";
printArray(numbers, size);
cout << "Sum of array: " << arraySum(numbers, size) << endl;
doubleArray(numbers, size);
cout << "After doubling: ";
printArray(numbers, size);
// 2D Array operations
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
int transposed[3][2];
cout << "\n2D Array Operations:\n";
cout << "====================\n";
printMatrix(matrix, 2);
// Note: For 2D arrays, column size must be specified
cout << "\nMatrix[1][2] = " << matrix[1][2] << endl;
return 0;
}
5. Best Practices & Common Errors
| Common Error | Example | Solution |
|---|---|---|
| Array Index Out of Bounds | int arr[5]; arr[5] = 10; |
Always check indices: 0 to size-1 |
| Forgetting Array Size | int arr[]; (no size specified) |
Specify size or initialize with values |
| Uninitialized Array | int arr[10]; (contains garbage) |
Always initialize: int arr[10] = {0}; |
| Wrong Loop Bounds | for(i=1; i<=size; i++) |
Use: for(i=0; i |
| Passing Wrong Size to Functions | void func(int arr[]) {...} |
Always pass size parameter: void func(int arr[], int size) |
| Assuming Arrays are Passed by Value | Modifying array in function affects original | Arrays are always passed by reference |
Best Practices
- Always initialize arrays when declaring them
- Use
constfor array sizes that shouldn't change - Check array bounds before accessing elements
- Use meaningful variable names for array indices
- Prefer range-based for loops when possible (C++11)
- Consider using
std::array(C++11) for fixed-size arrays - Use
std::vectorfor dynamic arrays
Performance Tips
- Access array elements sequentially for better cache performance
- Minimize array copying - pass by reference when possible
- Use local arrays for small, frequently accessed data
- Consider memory layout when designing algorithms
- Avoid multidimensional arrays with varying row lengths
Summary & Key Takeaways
1D Arrays Summary
- Linear collection of same-type elements
- Fixed size, contiguous memory
- Zero-based indexing (0 to n-1)
- Efficient random access O(1)
- Use for lists, sequences, vectors
2D Arrays Summary
- Matrix/table structure (rows × columns)
- Row-major memory layout
- Double indexing: [row][column]
- Use for matrices, grids, tables
- Common in image processing, games
When to Use Arrays
- Use arrays when: Size is fixed and known at compile time, need random access, working with multidimensional data
- Consider alternatives when: Size is dynamic (use
std::vector), need advanced operations (usestd::arrayin C++11) - Remember: Arrays are fundamental building blocks for more complex data structures
Next Steps
Mastering arrays is crucial for advancing in C++ programming. Practice with array-based algorithms, explore dynamic arrays with pointers, and learn about Standard Template Library (STL) containers like vector, array, and valarray for more advanced use cases.