- Arrays
1.1 One-Dimensional Arrays
1.1.1 Declaration Syntax
A one-dimensional array can be declared in three ways:
type name[size];type name[size] = {val1, val2, ...};type name[] = {val1, val2, ...};
Key characteristics:
- Elements occupy contiguous memory cells.
- All elements share the same data type.
- Indexing starts from 0.
| 10 | 20 | 30 | 40 | 50 | 60 |
|---|---|---|---|---|---|
| arr[0] | arr[1] | arr[2] | arr[3] | arr[4] | arr[5] |
#include <iostream>
using namespace std;
int main() {
// Method 1: declare then assign
int arr1[5];
arr1[0] = 10; arr1[1] = 20; arr1[2] = 30; arr1[3] = 40; arr1[4] = 50;
for (int idx = 0; idx < 5; idx++) {
cout << arr1[idx] << endl;
}
// Method 2: partial initialization → zeros fill the rest
int arr2[5] = {10, 20, 30};
for (int idx = 0; idx < 5; idx++) {
cout << arr2[idx] << endl;
}
// Method 3: size deduced from initializer
int arr3[] = {9,8,7,6,5,4,3,2,1};
for (int idx = 0; idx < 9; idx++) {
cout << arr3[idx] << endl;
}
return 0;
}
1.1.2 Array Name Properties
The array name provides:
- Total memory size of the array.
- The memory addres of the first element.
#include <iostream>
using namespace std;
int main() {
int data[10] = {1,2,3,4,5,6,7,8,9,10};
cout << "Array size in bytes: " << sizeof(data) << endl;
cout << "Element size: " << sizeof(data[0]) << endl;
cout << "Length: " << sizeof(data) / sizeof(data[0]) << endl;
cout << "Address of first element: " << data << endl;
cout << "Same as &data[0]: " << &data[0] << endl;
cout << "Address of second element: " << &data[1] << endl;
return 0;
}
Example: Find Maximum Value
#include <iostream>
using namespace std;
int main() {
int weights[5] = {300, 350, 200, 400, 250};
int maxVal = weights[0];
for (int i = 1; i < 5; i++) {
if (weights[i] > maxVal) maxVal = weights[i];
}
cout << "Max weight: " << maxVal << endl;
return 0;
}
Example: Reverse an Array
#include <iostream>
using namespace std;
int main() {
int values[] = {1,2,3,4,5,6,7};
int len = sizeof(values) / sizeof(values[0]);
for (int left = 0, right = len - 1; left < right; left++, right--) {
int tmp = values[left];
values[left] = values[right];
values[right] = tmp;
}
for (int i = 0; i < len; i++) cout << values[i] << endl;
return 0;
}
1.1.3 Bubble Sort
#include <iostream>
using namespace std;
int main() {
int nums[10] = {3,6,8,2,5,7,9,6,1,7};
int n = sizeof(nums) / sizeof(nums[0]);
// Outer loop: number of passes
for (int pass = 0; pass < n - 1; pass++) {
// Inner loop: compare adjacent elements
for (int i = 0; i < n - pass - 1; i++) {
if (nums[i] > nums[i+1]) {
int temp = nums[i];
nums[i] = nums[i+1];
nums[i+1] = temp;
}
}
}
for (int i = 0; i < n; i++) cout << nums[i] << endl;
return 0;
}
1.2 Two-Dimensional Arrays
1.2.1 Declaration
Four common ways to declare a 2D array:
type name[rows][cols];type name[rows][cols] = {{r1c1, r1c2}, {r2c1, r2c2}};type name[rows][cols] = {val1, val2, val3, ...};type name[][cols] = {val1, val2, ...};(rows are deduced, but cols must be given)
Access element: arr[row][col]
#include <iostream>
using namespace std;
int main() {
// Method 1: assign after declaration
int grid1[2][3];
grid1[0][0] = 1; grid1[0][1] = 2; grid1[0][2] = 3;
grid1[1][0] = 4; grid1[1][1] = 5; grid1[1][2] = 6;
for (int r = 0; r < 2; r++) {
for (int c = 0; c < 3; c++) cout << grid1[r][c] << " ";
cout << endl;
}
// Method 2: nested initializers (unassigned become 0)
int grid2[2][3] = {{1,2,3}, {4,5}};
for (int r = 0; r < 2; r++) {
for (int c = 0; c < 3; c++) cout << grid2[r][c] << " ";
cout << endl;
}
// Method 3: flat initializer
int grid3[2][3] = {1,2,3,4,5};
for (int r = 0; r < 2; r++) {
for (int c = 0; c < 3; c++) cout << grid3[r][c] << " ";
cout << endl;
}
// Method 4: omit row count
int grid4[][3] = {1,2,3,4,5,6};
for (int r = 0; r < 2; r++) {
for (int c = 0; c < 3; c++) cout << grid4[r][c] << " ";
cout << endl;
}
return 0;
}
1.2.2 Array Name for 2D Arrays
The name of a 2D array gives its total size and the address of the first element.
#include <iostream>
using namespace std;
int main() {
int matrix[2][3] = {{1,2,3}, {4,5,6}};
cout << "Total size: " << sizeof(matrix) << " bytes" << endl;
cout << "Size of first row: " << sizeof(matrix[0]) << " bytes" << endl;
cout << "Size of one element: " << sizeof(matrix[0][0]) << " bytes" << endl;
cout << "Number of rows: " << sizeof(matrix) / sizeof(matrix[0]) << endl;
cout << "Number of columns: " << sizeof(matrix[0]) / sizeof(matrix[0][0]) << endl;
cout << "First element address: " << &matrix[0][0] << endl;
return 0;
}
- Pointers
2.1 Basic Concepts
A pointer is a variable that stores a memory address. It provides indirect access to the data stored at that address.
2.2 Declaration and Usage
#include <iostream>
using namespace std;
int main() {
int value = 10;
int* ptr; // declare pointer
ptr = &value; // assign address
cout << "Address of value: " << &value << endl;
cout << "Pointer holds: " << ptr << endl;
cout << "Dereferenced: " << *ptr << endl; // prints 10
return 0;
}
2.3 Pointer Size
On 32-bit systems, a pointer occupies 4 bytes; on 64-bit systems, it occupies 8 bytes.
#include <iostream>
using namespace std;
int main() {
int x = 10;
int* ptr = &x;
cout << "Size of int*: " << sizeof(int*) << " bytes" << endl;
cout << "Size of ptr: " << sizeof(ptr) << " bytes" << endl;
return 0;
}
2.4 Null Pointers and Dangling Pointers
Null Pointer
A null pointer points to address 0. It is used for initialization and must not be dereferenced.
int* ptr = nullptr; // modern C++ uses nullptr
// *ptr = 20; // ERROR: cannot dereference null
Dangling Pointer
A dangling pointer points to memory that is not valid (e.g., a random address). Avoid such usage.
int* ptr = (int*)0x1100; // dangerous
// cout << *ptr; // may crash
2.5 Const and Pointers
Three combinations:
const int* p– pointer to constant: the value cannot be changed, but the pointer can point elsewhere.int* const p– constant pointer: the address cannot change, but the value can.const int* const p– both value and address are fixed.
2.6 Pointer Arithmetic with Arrays
The array name acts as a pointer to the first element. Incrementing the pointer moves to the next element.
#include <iostream>
using namespace std;
int main() {
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int* p = arr; // points to arr[0]
cout << "First element: " << *p << endl;
p++; // move to next element
cout << "Second element: " << *p << endl;
return 0;
}
2.7 Pointers in Functions: Pass by Address
Passing addresses allows a function to modify the original variables.
#include <iostream>
using namespace std;
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
int x = 3, y = 5;
swap(&x, &y);
cout << "x = " << x << ", y = " << y << endl; // x=5, y=3
return 0;
}
2.8 Combining Pointers, Arrays, and Functions
Example: bubble sort using pointer notation.
#include <iostream>
using namespace std;
void bubbleSort(int* data, int size) {
for (int pass = 0; pass < size - 1; pass++) {
for (int i = 0; i < size - pass - 1; i++) {
if (data[i] > data[i + 1]) {
int temp = data[i];
data[i] = data[i + 1];
data[i + 1] = temp;
}
}
}
}
void printArray(int* data, int size) {
for (int i = 0; i < size; i++) cout << data[i] << " ";
cout << endl;
}
int main() {
int values[] = {3,7,9,4,5,7,1,0,4,6};
int len = sizeof(values) / sizeof(values[0]);
bubbleSort(values, len);
printArray(values, len);
return 0;
}