第4天:指针基础
学习目标
深入理解指针的概念和使用,掌握指针运算和内存管理基础。
学习资源链接
📚 官方文档和教程
🎥 视频教程
📖 深入阅读
学习内容
1. 指针基础概念
- 指针的定义和声明
- 指针与内存地址
- 解引用操作符
- 空指针和野指针
2. 指针运算
- 指针算术运算
- 指针比较
- 指针的递增和递减
- 指针与数组的关系
3. 指针与数组
- 数组名作为指针
- 指针访问数组元素
- 指针遍历数组
- 多维数组的指针操作
4. 指针作为函数参数
- 指针参数传递
- 通过指针修改变量值
- 函数返回指针
- 指针参数的安全性
5. 指针的指针
重点概念和代码示例
指针声明与初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include <iostream> using namespace std;
void pointerBasics() { int* ptr; int value = 42; ptr = &value; cout << "value = " << value << endl; cout << "*ptr = " << *ptr << endl; cout << "ptr = " << ptr << endl; cout << "&value = " << &value << endl; *ptr = 100; cout << "value after *ptr = 100: " << value << endl; }
|
指针运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void pointerArithmetic() { int arr[] = {10, 20, 30, 40, 50}; int* ptr = arr; cout << "指针运算演示:" << endl; for (int i = 0; i < 5; i++) { cout << "ptr + " << i << " = " << ptr + i << ", value = " << *(ptr + i) << endl; } ptr++; cout << "ptr++ 后指向: " << *ptr << endl; int* ptr2 = &arr[4]; cout << "两指针差值: " << ptr2 - ptr << endl; }
|
指针与数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| void pointerAndArray() { int arr[] = {1, 2, 3, 4, 5}; cout << "arr = " << arr << endl; cout << "&arr[0] = " << &arr[0] << endl; cout << "arr == &arr[0]: " << (arr == &arr[0]) << endl; int* ptr = arr; for (int i = 0; i < 5; i++) { cout << "arr[" << i << "] = " << arr[i] << ", *(ptr + " << i << ") = " << *(ptr + i) << endl; } cout << "指针遍历: "; for (int* p = arr; p < arr + 5; p++) { cout << *p << " "; } cout << endl; }
|
指针作为函数参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; }
int* findMax(int* arr, int size) { if (size <= 0) return nullptr; int* maxPtr = arr; for (int i = 1; i < size; i++) { if (*(arr + i) > *maxPtr) { maxPtr = arr + i; } } return maxPtr; }
void pointerParameters() { int x = 10, y = 20; cout << "交换前: x = " << x << ", y = " << y << endl; swap(&x, &y); cout << "交换后: x = " << x << ", y = " << y << endl; int arr[] = {3, 7, 2, 9, 1}; int* maxPtr = findMax(arr, 5); if (maxPtr) { cout << "最大值: " << *maxPtr << ", 位置: " << (maxPtr - arr) << endl; } }
|
二级指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| void doublePointer() { int value = 100; int* ptr = &value; int** pptr = &ptr; cout << "二级指针演示:" << endl; cout << "value = " << value << endl; cout << "*ptr = " << *ptr << endl; cout << "**pptr = " << **pptr << endl; **pptr = 200; cout << "通过**pptr修改后,value = " << value << endl; int newValue = 300; *pptr = &newValue; cout << "*ptr现在指向newValue: " << *ptr << endl; }
|
实践练习
练习1:指针基础操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| void exercise1() { cout << "\n=== 练习1:指针基础操作 ===" << endl; int a = 10, b = 20, c = 30; int* ptr1 = &a; int* ptr2 = &b; cout << "a = " << a << ", 地址: " << &a << endl; cout << "b = " << b << ", 地址: " << &b << endl; cout << "c = " << c << ", 地址: " << &c << endl; cout << "*ptr1 = " << *ptr1 << endl; *ptr1 = 100; cout << "修改后 a = " << a << endl; ptr1 = &c; cout << "ptr1现在指向c: " << *ptr1 << endl; }
|
练习2:数组指针操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| void exercise2() { cout << "\n=== 练习2:数组指针操作 ===" << endl; int numbers[] = {5, 15, 25, 35, 45}; int size = sizeof(numbers) / sizeof(numbers[0]); int sum = 0; for (int* ptr = numbers; ptr < numbers + size; ptr++) { sum += *ptr; } cout << "数组元素之和: " << sum << endl; int* start = numbers; int* end = numbers + size - 1; while (start < end) { int temp = *start; *start = *end; *end = temp; start++; end--; } cout << "反转后的数组: "; for (int i = 0; i < size; i++) { cout << numbers[i] << " "; } cout << endl; }
|
练习3:字符串指针操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| int stringLength(const char* str) { const char* ptr = str; while (*ptr != '\0') { ptr++; } return ptr - str; }
void stringCopy(char* dest, const char* src) { while ((*dest++ = *src++) != '\0') { } }
void exercise3() { cout << "\n=== 练习3:字符串指针操作 ===" << endl; const char* message = "Hello, Pointers!"; cout << "字符串: " << message << endl; cout << "长度: " << stringLength(message) << endl; char buffer[50]; stringCopy(buffer, message); cout << "复制的字符串: " << buffer << endl; }
|
算法练习题
LeetCode相关题目
- 两数之和 - 使用指针优化查找
- 删除排序数组中的重复项 - 双指针技巧
- 移动零 - 指针操作数组
练习4:实现简单的动态数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| class SimpleVector { private: int* data; int size; int capacity; public: SimpleVector(int cap = 10) : size(0), capacity(cap) { data = new int[capacity]; } ~SimpleVector() { delete[] data; } void push_back(int value) { if (size >= capacity) { capacity *= 2; int* newData = new int[capacity]; for (int i = 0; i < size; i++) { newData[i] = data[i]; } delete[] data; data = newData; } data[size++] = value; } int& operator[](int index) { return data[index]; } int getSize() const { return size; } void print() const { for (int i = 0; i < size; i++) { cout << data[i] << " "; } cout << endl; } };
void exercise4() { cout << "\n=== 练习4:简单动态数组 ===" << endl; SimpleVector vec; for (int i = 1; i <= 15; i++) { vec.push_back(i * i); } cout << "动态数组内容: "; vec.print(); cout << "大小: " << vec.getSize() << endl; }
|
常见错误与注意事项
1. 野指针问题
1 2 3 4 5 6 7 8 9 10
| void dangerousPointer() { int* ptr; ptr = nullptr; if (ptr != nullptr) { *ptr = 10; } }
|
2. 指针越界
1 2 3 4 5 6 7 8 9 10 11 12
| void pointerBounds() { int arr[5] = {1, 2, 3, 4, 5}; int* ptr = arr; for (int i = 0; i < 5; i++) { *(ptr + i) = i + 1; } }
|
学习检查点
完整示例程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include <iostream> using namespace std;
int main() { cout << "=== C++ 指针基础学习 ===" << endl; pointerBasics(); pointerArithmetic(); pointerAndArray(); pointerParameters(); doublePointer(); exercise1(); exercise2(); exercise3(); exercise4(); return 0; }
|
返回第一周 | 上一天:数组与字符串 | 下一天:引用