🎯 C++ 指针和引用 - L25 进阶概念

掌握指针概念、指针运算、引用类型,理解C++的精髓

📚 指针和引用概述

什么是指针?

指针是一个变量,它存储的是另一个变量的内存地址。通过指针,我们可以间接访问和修改该变量的值。

  • 直接访问:通过变量名访问值
  • 间接访问:通过指针访问值
  • 灵活高效:可以动态管理内存
  • 传递引用:避免大数据拷贝
💡 指针的核心概念:
• 指针存储的是地址,不是值
• 使用 * 声明指针
• 使用 & 获取变量地址
• 使用 * 解引用指针(访问指向的值)

指针的基本语法

#include <iostream> using namespace std; int main() { int num = 42; // 声明指针:类型* 指针名 int* ptr; // 让指针指向变量:&取地址运算符 ptr = # // 输出变量信息 cout << "变量num的值:" << num << endl; // 42 cout << "变量num的地址:" << &num << endl; // 0x... cout << "指针ptr的值:" << ptr << endl; // 0x... (同num的地址) cout << "指针指向的值:" << *ptr << endl; // 42 (解引用) // 通过指针修改原变量 *ptr = 100; cout << "修改后num的值:" << num << endl; // 100 return 0; }

什么是引用?

引用是变量的别名,它和原变量共享同一块内存空间。引用必须在声明时初始化,且不能重新绑定到其他变量。

#include <iostream> using namespace std; int main() { int num = 42; // 声明引用:类型& 引用名 = 变量 int& ref = num; cout << "num的值:" << num << endl; // 42 cout << "ref的值:" << ref << endl; // 42 cout << "num的地址:" << &num << endl; // 0x... cout << "ref的地址:" << &ref << endl; // 0x... (相同) // 通过引用修改原变量 ref = 100; cout << "修改后num的值:" << num << endl; // 100 return 0; }
💡 指针 vs 引用:
指针:可以重新赋值、可以为nullptr、需要解引用
引用:必须初始化、不能重新绑定、直接使用
• 引用更安全,指针更灵活

⚙️ 指针基本操作

指针的声明和初始化

#include <iostream> using namespace std; int main() { // 方式1:先声明,后赋值 int* ptr1; int num1 = 10; ptr1 = &num1; // 方式2:声明时初始化 int num2 = 20; int* ptr2 = &num2; // 方式3:初始化为nullptr(空指针) int* ptr3 = nullptr; // 检查指针是否为空 if (ptr3 == nullptr) { cout << "ptr3是空指针" << endl; } cout << "*ptr1 = " << *ptr1 << endl; // 10 cout << "*ptr2 = " << *ptr2 << endl; // 20 return 0; }

指针运算

#include <iostream> using namespace std; int main() { int arr[] = {10, 20, 30, 40, 50}; int* ptr = arr; // 指向数组第一个元素 cout << "ptr[0] = " << ptr[0] << endl; // 10 cout << "ptr[1] = " << ptr[1] << endl; // 20 // 指针加法:移动到下一个元素 ptr++; cout << "ptr++后:*ptr = " << *ptr << endl; // 20 // 指针减法:移动回上一个元素 ptr--; cout << "ptr--后:*ptr = " << *ptr << endl; // 10 // 指针相减:计算两个指针之间的距离 int* ptr1 = &arr[0]; int* ptr2 = &arr[4]; cout << "距离:" << (ptr2 - ptr1) << endl; // 4 return 0; }

指针和数组的关系

#include <iostream> using namespace std; int main() { int arr[] = {10, 20, 30, 40, 50}; // 数组名就是指向第一个元素的指针 cout << "arr = " << arr << endl; cout << "&arr[0] = " << &arr[0] << endl; // 使用指针遍历数组 int* ptr = arr; for (int i = 0; i < 5; i++) { cout << "arr[" << i << "] = " << *(ptr + i) << endl; } // 等价写法 for (int i = 0; i < 5; i++) { cout << "arr[" << i << "] = " << ptr[i] << endl; } return 0; }
🎮 互动实验:指针可视化

输入一个数值,观察指针的操作过程

输入数值后点击按钮...

🛠️ 指针和引用的应用

指针作为函数参数

#include <iostream> using namespace std; // 使用指针交换两个数 void swapByPointer(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } // 使用引用交换两个数 void swapByReference(int& a, int& b) { int temp = a; a = b; b = temp; } int main() { int x = 10, y = 20; cout << "交换前:x = " << x << ", y = " << y << endl; // 使用指针 swapByPointer(&x, &y); cout << "指针交换后:x = " << x << ", y = " << y << endl; // 使用引用 swapByReference(x, y); cout << "引用交换后:x = " << x << ", y = " << y << endl; return 0; }

const指针和引用

#include <iostream> using namespace std; int main() { int num = 42; // const指针:指针本身不可变 int* const ptr1 = # // ptr1 = nullptr; // 错误!不能修改指针 *ptr1 = 100; // 可以修改指向的值 // 指向const的指针:不能通过指针修改值 const int* ptr2 = # // *ptr2 = 200; // 错误!不能修改值 ptr2 = nullptr; // 可以修改指针 // const引用:不能通过引用修改值 const int& ref = num; // ref = 300; // 错误! cout << "num = " << num << endl; // 100 return 0; }

返回引用的函数

#include <iostream> using namespace std; // 返回数组中最大值的引用 int& findMax(int arr[], int size) { int maxIndex = 0; for (int i = 1; i < size; i++) { if (arr[i] > arr[maxIndex]) { maxIndex = i; } } return arr[maxIndex]; // 返回引用 } int main() { int arr[] = {3, 1, 4, 1, 5, 9, 2, 6}; // 找到最大值并修改 int& maxVal = findMax(arr, 8); cout << "最大值:" << maxVal << endl; // 9 // 通过引用修改最大值 maxVal = 99; cout << "修改后:"; for (int i = 0; i < 8; i++) { cout << arr[i] << " "; } cout << endl; return 0; }

🚀 高级指针技术

二级指针(指针的指针)

#include <iostream> using namespace std; int main() { int num = 42; int* ptr = # // 一级指针 int** pptr = &ptr; // 二级指针 cout << "num = " << num << endl; // 42 cout << "*ptr = " << *ptr << endl; // 42 cout << "**pptr = " << **pptr << endl; // 42 // 通过二级指针修改值 **pptr = 100; cout << "修改后num = " << num << endl; // 100 return 0; }

函数指针

#include <iostream> using namespace std; // 定义几个函数 int add(int a, int b) { return a + b; } int multiply(int a, int b) { return a * b; } int main() { // 声明函数指针 int (*funcPtr)(int, int); // 指向add函数 funcPtr = add; cout << "add(3, 4) = " << funcPtr(3, 4) << endl; // 7 // 指向multiply函数 funcPtr = multiply; cout << "multiply(3, 4) = " << funcPtr(3, 4) << endl; // 12 return 0; }

实际应用:链表节点

#include <iostream> using namespace std; // 定义链表节点结构 struct Node { int data; Node* next; // 指向下一个节点的指针 }; // 创建新节点 Node* createNode(int value) { Node* newNode = new Node; newNode->data = value; newNode->next = nullptr; return newNode; } // 打印链表 void printList(Node* head) { Node* current = head; while (current != nullptr) { cout << current->data << " -> "; current = current->next; } cout << "NULL" << endl; } int main() { // 创建链表:1 -> 2 -> 3 -> NULL Node* head = createNode(1); head->next = createNode(2); head->next->next = createNode(3); cout << "链表:"; printList(head); return 0; }

📝 实战练习

📝 理解测试

以下代码的输出是什么?

#include <iostream> using namespace std; void modify(int* p) { *p = 100; } int main() { int x = 50; modify(&x); cout << x << endl; return 0; }
选择答案查看解析...
💻 综合挑战

题目:编写一个程序,实现以下功能:
1. 创建一个整数数组
2. 使用指针遍历数组并找出最大值和最小值
3. 使用指针交换最大值和最小值的位置
4. 输出交换后的数组

点击"生成代码框架"查看提示...