C++ Arrays Interview Questions
1D Arrays & 2D Arrays in C++
What is an array in C++ and what are its characteristics?
An array is a collection of elements of the same data type stored in contiguous memory locations.
Characteristics:
- Fixed size (defined at compile time)
- Elements stored in contiguous memory
- Index-based access (0-based indexing)
- All elements are of same data type
- Array name represents base address
- Size cannot be changed at runtime
How to declare and initialize a 1D array in C++?
// Different ways to declare and initialize 1D arrays
// 1. Declaration without initialization
int arr1[5]; // Declares array of 5 integers (garbage values)
// 2. Declaration with initialization
int arr2[5] = {1, 2, 3, 4, 5}; // All elements initialized
// 3. Size inferred from initialization
int arr3[] = {10, 20, 30, 40, 50}; // Size = 5 (inferred)
// 4. Partial initialization (rest set to 0)
int arr4[5] = {1, 2}; // arr4 = {1, 2, 0, 0, 0}
// 5. All elements to zero
int arr5[5] = {0}; // arr5 = {0, 0, 0, 0, 0}
// 6. Using const for array size (good practice)
const int SIZE = 10;
int arr6[SIZE];
// 1. Declaration without initialization
int arr1[5]; // Declares array of 5 integers (garbage values)
// 2. Declaration with initialization
int arr2[5] = {1, 2, 3, 4, 5}; // All elements initialized
// 3. Size inferred from initialization
int arr3[] = {10, 20, 30, 40, 50}; // Size = 5 (inferred)
// 4. Partial initialization (rest set to 0)
int arr4[5] = {1, 2}; // arr4 = {1, 2, 0, 0, 0}
// 5. All elements to zero
int arr5[5] = {0}; // arr5 = {0, 0, 0, 0, 0}
// 6. Using const for array size (good practice)
const int SIZE = 10;
int arr6[SIZE];
How to access and modify array elements in C++?
// Array access and modification
int numbers[5] = {10, 20, 30, 40, 50};
// Access elements using index
cout << "First element: " << numbers[0] << endl; // 10
cout << "Third element: " << numbers[2] << endl; // 30
// Modify elements
numbers[1] = 25; // Change second element to 25
numbers[4] = numbers[0] + 100; // 10 + 100 = 110
// Using loop to access all elements
for (int i = 0; i < 5; i++) {
cout << "Element " << i << ": " << numbers[i] << endl;
}
// Range-based for loop (C++11)
for (int num : numbers) {
cout << num << " ";
}
int numbers[5] = {10, 20, 30, 40, 50};
// Access elements using index
cout << "First element: " << numbers[0] << endl; // 10
cout << "Third element: " << numbers[2] << endl; // 30
// Modify elements
numbers[1] = 25; // Change second element to 25
numbers[4] = numbers[0] + 100; // 10 + 100 = 110
// Using loop to access all elements
for (int i = 0; i < 5; i++) {
cout << "Element " << i << ": " << numbers[i] << endl;
}
// Range-based for loop (C++11)
for (int num : numbers) {
cout << num << " ";
}
What is the memory representation of a 1D array?
Memory Representation:
int arr[5] = {10, 20, 30, 40, 50};
Index: 0 1 2 3 4
Value: 10 20 30 40 50
Address: 1000 1004 1008 1012 1016
// Assuming int size = 4 bytes
arr[0] at address 1000
arr[1] at address 1004 (1000 + 4)
arr[2] at address 1008 (1000 + 8)
... and so on
Formula for element address: Base Address + (index * sizeof(data type))
int arr[5] = {10, 20, 30, 40, 50};
Index: 0 1 2 3 4
Value: 10 20 30 40 50
Address: 1000 1004 1008 1012 1016
// Assuming int size = 4 bytes
arr[0] at address 1000
arr[1] at address 1004 (1000 + 4)
arr[2] at address 1008 (1000 + 8)
... and so on
How to declare and initialize a 2D array in C++?
// Different ways to declare and initialize 2D arrays
// 1. Declaration with dimensions
int matrix1[3][4]; // 3 rows, 4 columns
// 2. Declaration with initialization
int matrix2[2][3] = {
{1, 2, 3}, // Row 0
{4, 5, 6} // Row 1
};
// 3. Inferred row count
int matrix3[][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
}; // 3 rows inferred
// 4. Linear initialization
int matrix4[2][3] = {1, 2, 3, 4, 5, 6};
// Equivalent to {{1,2,3}, {4,5,6}}
// 5. Partial initialization
int matrix5[3][3] = {
{1}, // {1, 0, 0}
{4, 5}, // {4, 5, 0}
{7, 8, 9} // {7, 8, 9}
};
// 1. Declaration with dimensions
int matrix1[3][4]; // 3 rows, 4 columns
// 2. Declaration with initialization
int matrix2[2][3] = {
{1, 2, 3}, // Row 0
{4, 5, 6} // Row 1
};
// 3. Inferred row count
int matrix3[][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
}; // 3 rows inferred
// 4. Linear initialization
int matrix4[2][3] = {1, 2, 3, 4, 5, 6};
// Equivalent to {{1,2,3}, {4,5,6}}
// 5. Partial initialization
int matrix5[3][3] = {
{1}, // {1, 0, 0}
{4, 5}, // {4, 5, 0}
{7, 8, 9} // {7, 8, 9}
};
How to access and traverse a 2D array using nested loops?
// Accessing and traversing 2D arrays
const int ROWS = 3;
const int COLS = 4;
int matrix[ROWS][COLS];
// Initialize with values
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
matrix[i][j] = i * COLS + j + 1;
}
}
// Print row-wise (normal order)
cout << "Row-wise traversal:" << endl;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
cout << matrix[i][j] << "\t";
}
cout << endl;
}
// Print column-wise
cout << "\nColumn-wise traversal:" << endl;
for (int j = 0; j < COLS; j++) {
for (int i = 0; i < ROWS; i++) {
cout << matrix[i][j] << "\t";
}
cout << endl;
}
// Access specific element
int element = matrix[1][2]; // Row 1, Column 2
matrix[0][3] = 99; // Modify element
const int ROWS = 3;
const int COLS = 4;
int matrix[ROWS][COLS];
// Initialize with values
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
matrix[i][j] = i * COLS + j + 1;
}
}
// Print row-wise (normal order)
cout << "Row-wise traversal:" << endl;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
cout << matrix[i][j] << "\t";
}
cout << endl;
}
// Print column-wise
cout << "\nColumn-wise traversal:" << endl;
for (int j = 0; j < COLS; j++) {
for (int i = 0; i < ROWS; i++) {
cout << matrix[i][j] << "\t";
}
cout << endl;
}
// Access specific element
int element = matrix[1][2]; // Row 1, Column 2
matrix[0][3] = 99; // Modify element
What is the memory representation of a 2D array?
Memory Representation (Row-major order in C++):
int arr[2][3] = {{1,2,3}, {4,5,6}};
Memory Layout (contiguous):
Index: [0][0] [0][1] [0][2] [1][0] [1][1] [1][2]
Value: 1 2 3 4 5 6
Address: 1000 1004 1008 1012 1016 1020
Formula for element arr[i][j]:
Address = Base + (i * COLS + j) * sizeof(element)
Example: arr[1][1] address = 1000 + (1*3 + 1)*4 = 1016
C++ uses row-major order (rows stored consecutively).
int arr[2][3] = {{1,2,3}, {4,5,6}};
Memory Layout (contiguous):
Index: [0][0] [0][1] [0][2] [1][0] [1][1] [1][2]
Value: 1 2 3 4 5 6
Address: 1000 1004 1008 1012 1016 1020
Formula for element arr[i][j]:
Address = Base + (i * COLS + j) * sizeof(element)
Example: arr[1][1] address = 1000 + (1*3 + 1)*4 = 1016
What is the difference between array and pointer in C++?
| Aspect | Array | Pointer |
|---|---|---|
| Declaration | int arr[5]; | int *ptr; |
| Sizeof | sizeof(arr) = 5 * sizeof(int) | sizeof(ptr) = size of pointer (usually 4/8 bytes) |
| Assignment | Cannot be reassigned | Can point to different locations |
| Address of | &arr = same as arr (decays to pointer) | &ptr = address of pointer variable |
| Increment | arr++ not allowed | ptr++ allowed (pointer arithmetic) |
| Memory | Allocates memory for elements | Only stores an address |
// Array decays to pointer in most contexts
int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr; // Array name decays to pointer to first element
cout << arr[2] << endl; // 3
cout << *(arr + 2) << endl; // Also 3 (pointer arithmetic)
cout << ptr[2] << endl; // 3 (ptr can be used like array)
int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr; // Array name decays to pointer to first element
cout << arr[2] << endl; // 3
cout << *(arr + 2) << endl; // Also 3 (pointer arithmetic)
cout << ptr[2] << endl; // 3 (ptr can be used like array)
How to pass arrays to functions in C++?
// Different ways to pass arrays to functions
// 1. Pass by pointer (size as separate parameter)
void printArray1(int* arr, int size) {
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
}
// 2. Pass as array with size
void printArray2(int arr[], int size) {
// Same as pointer version
}
// 3. For 1D array with fixed size
void printArray3(int (&arr)[5]) { // Reference to array of size 5
for (int num : arr) {
cout << num << " ";
}
}
// 4. Pass 2D array - must specify column size
void printMatrix1(int mat[][3], int rows) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < 3; j++) {
cout << mat[i][j] << " ";
}
cout << endl;
}
}
// Usage
int main() {
int arr[5] = {1, 2, 3, 4, 5};
int matrix[2][3] = {{1,2,3}, {4,5,6}};
printArray1(arr, 5);
printMatrix1(matrix, 2);
return 0;
}
// 1. Pass by pointer (size as separate parameter)
void printArray1(int* arr, int size) {
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
}
// 2. Pass as array with size
void printArray2(int arr[], int size) {
// Same as pointer version
}
// 3. For 1D array with fixed size
void printArray3(int (&arr)[5]) { // Reference to array of size 5
for (int num : arr) {
cout << num << " ";
}
}
// 4. Pass 2D array - must specify column size
void printMatrix1(int mat[][3], int rows) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < 3; j++) {
cout << mat[i][j] << " ";
}
cout << endl;
}
}
// Usage
int main() {
int arr[5] = {1, 2, 3, 4, 5};
int matrix[2][3] = {{1,2,3}, {4,5,6}};
printArray1(arr, 5);
printMatrix1(matrix, 2);
return 0;
}
How to find the size/length of an array in C++?
// Different methods to find array size
// 1. Using sizeof operator
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// Total size in bytes
int totalBytes = sizeof(arr); // 10 * 4 = 40 (assuming int=4 bytes)
// Size of one element
int elementSize = sizeof(arr[0]); // 4 bytes
// Number of elements
int length = sizeof(arr) / sizeof(arr[0]); // 40 / 4 = 10
cout << "Array has " << length << " elements" << endl;
// 2. For 2D arrays
int matrix[3][4];
int rows = sizeof(matrix) / sizeof(matrix[0]); // 3
int cols = sizeof(matrix[0]) / sizeof(matrix[0][0]); // 4
cout << "Matrix: " << rows << " rows, " << cols << " columns" << endl;
// WARNING: Doesn't work with pointer to array!
void printSize(int* arr) {
// sizeof(arr) here = size of pointer, not array!
cout << "Wrong size: " << sizeof(arr) << endl;
}
// 1. Using sizeof operator
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// Total size in bytes
int totalBytes = sizeof(arr); // 10 * 4 = 40 (assuming int=4 bytes)
// Size of one element
int elementSize = sizeof(arr[0]); // 4 bytes
// Number of elements
int length = sizeof(arr) / sizeof(arr[0]); // 40 / 4 = 10
cout << "Array has " << length << " elements" << endl;
// 2. For 2D arrays
int matrix[3][4];
int rows = sizeof(matrix) / sizeof(matrix[0]); // 3
int cols = sizeof(matrix[0]) / sizeof(matrix[0][0]); // 4
cout << "Matrix: " << rows << " rows, " << cols << " columns" << endl;
// WARNING: Doesn't work with pointer to array!
void printSize(int* arr) {
// sizeof(arr) here = size of pointer, not array!
cout << "Wrong size: " << sizeof(arr) << endl;
}
How to implement linear search in an array?
// Linear search implementation
int linearSearch(int arr[], int size, int target) {
for (int i = 0; i < size; i++) {
if (arr[i] == target) {
return i; // Return index if found
}
}
return -1; // Return -1 if not found
}
// Usage example
int main() {
int numbers[] = {45, 23, 67, 89, 12, 34, 56, 78, 90, 11};
int size = sizeof(numbers) / sizeof(numbers[0]);
int target;
cout << "Enter number to search: ";
cin >> target;
int index = linearSearch(numbers, size, target);
if (index != -1) {
cout << target << " found at index " << index << endl;
} else {
cout << target << " not found in array" << endl;
}
return 0;
}
// Time Complexity: O(n) where n is array size
// Best case: O(1) (element at first position)
// Worst case: O(n) (element not present or at last)
int linearSearch(int arr[], int size, int target) {
for (int i = 0; i < size; i++) {
if (arr[i] == target) {
return i; // Return index if found
}
}
return -1; // Return -1 if not found
}
// Usage example
int main() {
int numbers[] = {45, 23, 67, 89, 12, 34, 56, 78, 90, 11};
int size = sizeof(numbers) / sizeof(numbers[0]);
int target;
cout << "Enter number to search: ";
cin >> target;
int index = linearSearch(numbers, size, target);
if (index != -1) {
cout << target << " found at index " << index << endl;
} else {
cout << target << " not found in array" << endl;
}
return 0;
}
// Time Complexity: O(n) where n is array size
// Best case: O(1) (element at first position)
// Worst case: O(n) (element not present or at last)
How to reverse an array in C++?
// Reverse array using two-pointer technique
void reverseArray(int arr[], int size) {
int start = 0;
int end = size - 1;
while (start < end) {
// Swap elements
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
// Move pointers
start++;
end--;
}
}
// Alternative using for loop
void reverseArrayFor(int arr[], int size) {
for (int i = 0; i < size/2; i++) {
int temp = arr[i];
arr[i] = arr[size - 1 - i];
arr[size - 1 - i] = temp;
}
}
// Example usage
int main() {
int arr[] = {1, 2, 3, 4, 5};
int size = sizeof(arr) / sizeof(arr[0]);
cout << "Original array: ";
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
reverseArray(arr, size);
cout << "\nReversed array: ";
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
return 0;
}
void reverseArray(int arr[], int size) {
int start = 0;
int end = size - 1;
while (start < end) {
// Swap elements
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
// Move pointers
start++;
end--;
}
}
// Alternative using for loop
void reverseArrayFor(int arr[], int size) {
for (int i = 0; i < size/2; i++) {
int temp = arr[i];
arr[i] = arr[size - 1 - i];
arr[size - 1 - i] = temp;
}
}
// Example usage
int main() {
int arr[] = {1, 2, 3, 4, 5};
int size = sizeof(arr) / sizeof(arr[0]);
cout << "Original array: ";
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
reverseArray(arr, size);
cout << "\nReversed array: ";
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
return 0;
}
How to find the sum of all elements in a 2D array?
// Calculate sum of all elements in 2D array
int sum2DArray(int mat[][3], int rows) {
int total = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < 3; j++) {
total += mat[i][j];
}
}
return total;
}
// Alternative with dynamic array size
int sum2DArrayGeneral(int** mat, int rows, int cols) {
int sum = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
sum += mat[i][j];
}
}
return sum;
}
// Usage example
int main() {
int matrix[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int total = sum2DArray(matrix, 3);
cout << "Sum of all elements: " << total << endl; // 45
// Also find row-wise and column-wise sums
for (int i = 0; i < 3; i++) {
int rowSum = 0;
for (int j = 0; j < 3; j++) {
rowSum += matrix[i][j];
}
cout << "Sum of row " << i << ": " << rowSum << endl;
}
return 0;
}
int sum2DArray(int mat[][3], int rows) {
int total = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < 3; j++) {
total += mat[i][j];
}
}
return total;
}
// Alternative with dynamic array size
int sum2DArrayGeneral(int** mat, int rows, int cols) {
int sum = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
sum += mat[i][j];
}
}
return sum;
}
// Usage example
int main() {
int matrix[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int total = sum2DArray(matrix, 3);
cout << "Sum of all elements: " << total << endl; // 45
// Also find row-wise and column-wise sums
for (int i = 0; i < 3; i++) {
int rowSum = 0;
for (int j = 0; j < 3; j++) {
rowSum += matrix[i][j];
}
cout << "Sum of row " << i << ": " << rowSum << endl;
}
return 0;
}
What are the limitations of arrays in C++?
Limitations of arrays:
- Fixed size: Cannot be resized at runtime
- Memory waste: If allocated more than needed
- No bounds checking: Accessing out of bounds causes undefined behavior
- Contiguous memory requirement: May not find large contiguous block
- Insertion/deletion: Expensive operations (need to shift elements)
- Homogeneous elements: All elements must be same type
- No built-in methods: No length(), sort(), search() methods
- Array decay: Loses size information when passed to functions
Solution: Use C++ Standard Library containers like vector, array (C++11), or deque which overcome these limitations.
How to find the largest and smallest element in an array?
// Find min and max in array
void findMinMax(int arr[], int size, int &min, int &max) {
// Initialize with first element
min = arr[0];
max = arr[0];
for (int i = 1; i < size; i++) {
if (arr[i] < min) {
min = arr[i];
}
if (arr[i] > max) {
max = arr[i];
}
}
}
// Alternative using single pass
void findMinMax2(int arr[], int size) {
int min = arr[0];
int max = arr[0];
for (int i = 1; i < size; i++) {
min = (arr[i] < min) ? arr[i] : min;
max = (arr[i] > max) ? arr[i] : max;
}
cout << "Minimum: " << min << endl;
cout << "Maximum: " << max << endl;
}
// Usage
int main() {
int numbers[] = {23, 45, 12, 67, 89, 34, 56, 78, 9, 41};
int size = sizeof(numbers) / sizeof(numbers[0]);
int minVal, maxVal;
findMinMax(numbers, size, minVal, maxVal);
cout << "Array: ";
for (int i = 0; i < size; i++) {
cout << numbers[i] << " ";
}
cout << "\nSmallest: " << minVal << endl;
cout << "Largest: " << maxVal << endl;
// Also works with 2D arrays
int matrix[3][3] = {{5, 12, 3}, {8, 1, 9}, {4, 7, 2}};
int minMatrix = matrix[0][0], maxMatrix = matrix[0][0];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (matrix[i][j] < minMatrix) minMatrix = matrix[i][j];
if (matrix[i][j] > maxMatrix) maxMatrix = matrix[i][j];
}
}
cout << "\n2D Array Min: " << minMatrix << ", Max: " << maxMatrix << endl;
return 0;
}
void findMinMax(int arr[], int size, int &min, int &max) {
// Initialize with first element
min = arr[0];
max = arr[0];
for (int i = 1; i < size; i++) {
if (arr[i] < min) {
min = arr[i];
}
if (arr[i] > max) {
max = arr[i];
}
}
}
// Alternative using single pass
void findMinMax2(int arr[], int size) {
int min = arr[0];
int max = arr[0];
for (int i = 1; i < size; i++) {
min = (arr[i] < min) ? arr[i] : min;
max = (arr[i] > max) ? arr[i] : max;
}
cout << "Minimum: " << min << endl;
cout << "Maximum: " << max << endl;
}
// Usage
int main() {
int numbers[] = {23, 45, 12, 67, 89, 34, 56, 78, 9, 41};
int size = sizeof(numbers) / sizeof(numbers[0]);
int minVal, maxVal;
findMinMax(numbers, size, minVal, maxVal);
cout << "Array: ";
for (int i = 0; i < size; i++) {
cout << numbers[i] << " ";
}
cout << "\nSmallest: " << minVal << endl;
cout << "Largest: " << maxVal << endl;
// Also works with 2D arrays
int matrix[3][3] = {{5, 12, 3}, {8, 1, 9}, {4, 7, 2}};
int minMatrix = matrix[0][0], maxMatrix = matrix[0][0];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (matrix[i][j] < minMatrix) minMatrix = matrix[i][j];
if (matrix[i][j] > maxMatrix) maxMatrix = matrix[i][j];
}
}
cout << "\n2D Array Min: " << minMatrix << ", Max: " << maxMatrix << endl;
return 0;
}
How to implement matrix multiplication using 2D arrays?
// Matrix multiplication: A[m][n] * B[n][p] = C[m][p]
void multiplyMatrices(int A[][3], int B[][2], int C[][2], int m, int n, int p) {
// Initialize result matrix to 0
for (int i = 0; i < m; i++) {
for (int j = 0; j < p; j++) {
C[i][j] = 0;
}
}
// Multiply matrices
for (int i = 0; i < m; i++) {
for (int j = 0; j < p; j++) {
for (int k = 0; k < n; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
}
// Usage example
int main() {
int A[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
int B[3][2] = {
{7, 8},
{9, 10},
{11, 12}
};
int C[2][2]; // Result matrix
multiplyMatrices(A, B, C, 2, 3, 2);
cout << "Matrix A (2x3):" << endl;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
cout << A[i][j] << "\t";
}
cout << endl;
}
cout << "\nMatrix B (3x2):" << endl;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
cout << B[i][j] << "\t";
}
cout << endl;
}
cout << "\nResult C = A * B (2x2):" << endl;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
cout << C[i][j] << "\t";
}
cout << endl;
}
return 0;
}
/* Output:
C[0][0] = 1*7 + 2*9 + 3*11 = 58
C[0][1] = 1*8 + 2*10 + 3*12 = 64
C[1][0] = 4*7 + 5*9 + 6*11 = 139
C[1][1] = 4*8 + 5*10 + 6*12 = 154 */
void multiplyMatrices(int A[][3], int B[][2], int C[][2], int m, int n, int p) {
// Initialize result matrix to 0
for (int i = 0; i < m; i++) {
for (int j = 0; j < p; j++) {
C[i][j] = 0;
}
}
// Multiply matrices
for (int i = 0; i < m; i++) {
for (int j = 0; j < p; j++) {
for (int k = 0; k < n; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
}
// Usage example
int main() {
int A[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
int B[3][2] = {
{7, 8},
{9, 10},
{11, 12}
};
int C[2][2]; // Result matrix
multiplyMatrices(A, B, C, 2, 3, 2);
cout << "Matrix A (2x3):" << endl;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
cout << A[i][j] << "\t";
}
cout << endl;
}
cout << "\nMatrix B (3x2):" << endl;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
cout << B[i][j] << "\t";
}
cout << endl;
}
cout << "\nResult C = A * B (2x2):" << endl;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
cout << C[i][j] << "\t";
}
cout << endl;
}
return 0;
}
/* Output:
C[0][0] = 1*7 + 2*9 + 3*11 = 58
C[0][1] = 1*8 + 2*10 + 3*12 = 64
C[1][0] = 4*7 + 5*9 + 6*11 = 139
C[1][1] = 4*8 + 5*10 + 6*12 = 154 */
What is array bounds checking and why is it important?
// C++ does NOT perform array bounds checking at runtime
int arr[5] = {1, 2, 3, 4, 5};
// These compile but cause UNDEFINED BEHAVIOR
int x = arr[5]; // Index 5 is out of bounds (valid indices: 0-4)
arr[-1] = 10; // Negative index - undefined behavior
arr[10] = 20; // Far out of bounds - could corrupt memory
// Common consequences:
// 1. Program crashes (segmentation fault)
// 2. Reads garbage values
// 3. Corrupts other variables
// 4. Security vulnerabilities (buffer overflow attacks)
// Safe practices:
// 1. Always check bounds manually
int index = 3;
if (index >= 0 && index < 5) {
int value = arr[index]; // Safe access
}
// 2. Use std::array (C++11) for bounds checking in debug mode
#include <array>
std::array<int, 5> stdArr = {1, 2, 3, 4, 5};
// stdArr.at(5) throws std::out_of_range exception
// 3. Use vectors with bounds checking
#include <vector>
std::vector<int> vec = {1, 2, 3, 4, 5};
// vec.at(5) throws std::out_of_range
int arr[5] = {1, 2, 3, 4, 5};
// These compile but cause UNDEFINED BEHAVIOR
int x = arr[5]; // Index 5 is out of bounds (valid indices: 0-4)
arr[-1] = 10; // Negative index - undefined behavior
arr[10] = 20; // Far out of bounds - could corrupt memory
// Common consequences:
// 1. Program crashes (segmentation fault)
// 2. Reads garbage values
// 3. Corrupts other variables
// 4. Security vulnerabilities (buffer overflow attacks)
// Safe practices:
// 1. Always check bounds manually
int index = 3;
if (index >= 0 && index < 5) {
int value = arr[index]; // Safe access
}
// 2. Use std::array (C++11) for bounds checking in debug mode
#include <array>
std::array<int, 5> stdArr = {1, 2, 3, 4, 5};
// stdArr.at(5) throws std::out_of_range exception
// 3. Use vectors with bounds checking
#include <vector>
std::vector<int> vec = {1, 2, 3, 4, 5};
// vec.at(5) throws std::out_of_range
How to sort an array using bubble sort algorithm?
// Bubble sort implementation
void bubbleSort(int arr[], int size) {
for (int i = 0; i < size - 1; i++) {
// Last i elements are already sorted
for (int j = 0; j < size - i - 1; j++) {
// Compare adjacent elements
if (arr[j] > arr[j + 1]) {
// Swap if in wrong order
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
// Optimized bubble sort with early termination
void bubbleSortOptimized(int arr[], int size) {
for (int i = 0; i < size - 1; i++) {
bool swapped = false;
for (int j = 0; j < size - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
}
}
// If no swaps, array is sorted
if (!swapped) break;
}
}
// Usage
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int size = sizeof(arr) / sizeof(arr[0]);
cout << "Original array: ";
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
bubbleSort(arr, size);
cout << "\nSorted array: ";
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
return 0;
}
// Time Complexity: O(n²) worst and average case
// Time Complexity: O(n) best case (already sorted, optimized version)
// Space Complexity: O(1) (in-place sorting)
void bubbleSort(int arr[], int size) {
for (int i = 0; i < size - 1; i++) {
// Last i elements are already sorted
for (int j = 0; j < size - i - 1; j++) {
// Compare adjacent elements
if (arr[j] > arr[j + 1]) {
// Swap if in wrong order
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
// Optimized bubble sort with early termination
void bubbleSortOptimized(int arr[], int size) {
for (int i = 0; i < size - 1; i++) {
bool swapped = false;
for (int j = 0; j < size - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
}
}
// If no swaps, array is sorted
if (!swapped) break;
}
}
// Usage
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int size = sizeof(arr) / sizeof(arr[0]);
cout << "Original array: ";
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
bubbleSort(arr, size);
cout << "\nSorted array: ";
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
return 0;
}
// Time Complexity: O(n²) worst and average case
// Time Complexity: O(n) best case (already sorted, optimized version)
// Space Complexity: O(1) (in-place sorting)
How to work with character arrays (strings) in C++?
// Character arrays as strings
// 1. Declaration and initialization
char str1[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
char str2[] = "Hello"; // Automatically adds null terminator
char str3[20] = "Hello World";
// 2. String operations without library functions
// String length
int stringLength(char str[]) {
int length = 0;
while (str[length] != '\0') {
length++;
}
return length;
}
// String copy
void stringCopy(char dest[], char src[]) {
int i = 0;
while (src[i] != '\0') {
dest[i] = src[i];
i++;
}
dest[i] = '\0'; // Don't forget null terminator!
}
// String concatenation
void stringConcat(char dest[], char src[]) {
int destLen = stringLength(dest);
int i = 0;
while (src[i] != '\0') {
dest[destLen + i] = src[i];
i++;
}
dest[destLen + i] = '\0';
}
// 3. Using cstring library
#include <cstring>
char src[] = "Hello";
char dest[50];
strcpy(dest, src); // Copy
strcat(dest, " World"); // Concatenate
int len = strlen(dest); // Length
int cmp = strcmp("Hello", "World"); // Compare
// 4. Important: Always ensure enough space!
char small[5] = "Hello"; // WRONG: No space for null terminator!
char correct[6] = "Hello"; // CORRECT: 5 chars + '\0'
// 1. Declaration and initialization
char str1[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
char str2[] = "Hello"; // Automatically adds null terminator
char str3[20] = "Hello World";
// 2. String operations without library functions
// String length
int stringLength(char str[]) {
int length = 0;
while (str[length] != '\0') {
length++;
}
return length;
}
// String copy
void stringCopy(char dest[], char src[]) {
int i = 0;
while (src[i] != '\0') {
dest[i] = src[i];
i++;
}
dest[i] = '\0'; // Don't forget null terminator!
}
// String concatenation
void stringConcat(char dest[], char src[]) {
int destLen = stringLength(dest);
int i = 0;
while (src[i] != '\0') {
dest[destLen + i] = src[i];
i++;
}
dest[destLen + i] = '\0';
}
// 3. Using cstring library
#include <cstring>
char src[] = "Hello";
char dest[50];
strcpy(dest, src); // Copy
strcat(dest, " World"); // Concatenate
int len = strlen(dest); // Length
int cmp = strcmp("Hello", "World"); // Compare
// 4. Important: Always ensure enough space!
char small[5] = "Hello"; // WRONG: No space for null terminator!
char correct[6] = "Hello"; // CORRECT: 5 chars + '\0'
What are dynamic arrays and how to create them in C++?
// Dynamic arrays using new and delete
// 1. Creating dynamic 1D array
int size;
cout << "Enter array size: ";
cin >> size;
// Allocate memory
int* dynamicArray = new int[size];
// Initialize and use
for (int i = 0; i < size; i++) {
dynamicArray[i] = i * 10;
}
// Print
for (int i = 0; i < size; i++) {
cout << dynamicArray[i] << " ";
}
// MUST free memory
delete[] dynamicArray;
// 2. Creating dynamic 2D array
int rows, cols;
cout << "\nEnter rows and columns: ";
cin >> rows >> cols;
// Allocate array of pointers (rows)
int** dynamic2D = new int*[rows];
// Allocate each row
for (int i = 0; i < rows; i++) {
dynamic2D[i] = new int[cols];
}
// Initialize
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
dynamic2D[i][j] = i * cols + j;
}
}
// Print
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cout << dynamic2D[i][j] << "\t";
}
cout << endl;
}
// Free memory in reverse order
for (int i = 0; i < rows; i++) {
delete[] dynamic2D[i];
}
delete[] dynamic2D;
// 3. Better alternative: Use std::vector
#include <vector>
std::vector<int> vec(size); // No manual memory management needed
std::vector<std::vector<int>> matrix(rows, std::vector<int>(cols));
// 1. Creating dynamic 1D array
int size;
cout << "Enter array size: ";
cin >> size;
// Allocate memory
int* dynamicArray = new int[size];
// Initialize and use
for (int i = 0; i < size; i++) {
dynamicArray[i] = i * 10;
}
for (int i = 0; i < size; i++) {
cout << dynamicArray[i] << " ";
}
// MUST free memory
delete[] dynamicArray;
// 2. Creating dynamic 2D array
int rows, cols;
cout << "\nEnter rows and columns: ";
cin >> rows >> cols;
// Allocate array of pointers (rows)
int** dynamic2D = new int*[rows];
// Allocate each row
for (int i = 0; i < rows; i++) {
dynamic2D[i] = new int[cols];
}
// Initialize
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
dynamic2D[i][j] = i * cols + j;
}
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cout << dynamic2D[i][j] << "\t";
}
cout << endl;
}
// Free memory in reverse order
for (int i = 0; i < rows; i++) {
delete[] dynamic2D[i];
}
delete[] dynamic2D;
// 3. Better alternative: Use std::vector
#include <vector>
std::vector<int> vec(size); // No manual memory management needed
std::vector<std::vector<int>> matrix(rows, std::vector<int>(cols));
Array Best Practices:
- Always initialize arrays (avoid garbage values)
- Use const for array sizes when known at compile time
- Check array bounds before access to prevent buffer overflows
- Prefer std::array (C++11) or std::vector over raw arrays when possible
- Use range-based for loops (C++11) for cleaner iteration
- For strings, prefer std::string over character arrays
- When passing arrays to functions, always pass the size as a parameter
- For large arrays, consider dynamic allocation or using containers