一、 指针的作用
指针(Pointer)是 C++ 中的一种特殊变量,它存储的是另一个变量的内存地址,而不是具体的值。
指针有以下作用:
- 直接操作内存地址,提高效率。
- 动态内存分配,如
new
和delete
。 - 数组与字符串的操作,如遍历数组。
- 函数参数传递,提高性能,避免数据拷贝。
- 实现数据结构,如链表、树等。
二、 指针的声明、取地址和解引用
(1) 指针的声明
作用:
定义指针变量。
语法:
数据类型* 指针变量名;
示例:
int a = 10; // 定义变量
int* p = &a; // 定义指针,存储变量 a 的地址
(2) &
取地址运算符
作用:
用于获取变量的内存地址。
示例:
int x = 5;
cout << &x << endl; // 输出 x 的内存地址
(3) *
解引用(访问指针指向的值)
作用:
用于访问指针指向的变量值。
示例:
int a = 10;
int* p = &a; // 指针 p 指向 a
cout << *p << endl; // 输出 10
示例——使用指针的声明、取地址和解引用:
#include <iostream>
using namespace std;
int main() {
int a = 10;
int* p = &a; // 定义指针 p
cout << "a 的值: " << a << endl;
cout << "a 的地址: " << &a << endl;
cout << "指针 p 的值(a 的地址): " << p << endl;
cout << "指针 p 指向的值: " << *p << endl;
system("pause");
return 0;
}
三、特殊的指针
(1)三种 const 指针
类型 | 定义方式 | 能修改指向的值? | 能修改指针本身? | 适用场景 |
---|---|---|---|---|
指向常量的指针 | const int* p; | ❌ | ✅ | 保护数据不被修改 |
常量指针 | int* const p; | ✅ | ❌ | 确保指针指向固定 |
指向常量的常量指针 | const int* const p; | ❌ | ❌ | 最高级别的保护 |
示例:
#include <iostream>
using namespace std;
int main() {
// 1、指向常量的指针
int a = 10, b = 20;
const int* p1 = &a; // p 指向的值不可修改
cout << "*p1 = " << *p1 << endl;
// *p1 = 20; // 错误:指向的值不可修改
p1 = &b; // 正确:指针本身可以改变
// 2、常量指针
a = 10, b = 20;
int* const p2 = &a; // p 是常量指针
*p2 = 30; // 正确:可以修改指向的值
// p2 = &b; // 错误:不能更改指针本身
// 3、指向常量的常量指针
a = 10, b = 20;
const int* const p = &a; // 指针和指向的值都不可变
// *p = 30; // 错误:指向的值不可修改
// p = &b; // 错误:指针本身不可修改
system("pause");
return 0;
}
(2) nullptr
vs NULL
关键字 | C++ 版本 | 作用 |
---|---|---|
NULL | C/C++98 | 传统空指针,实际是 0 |
nullptr | C++11 | 更安全的空指针类型 |
示例:
#include <iostream>
using namespace std;
int main() {
int* p1 = NULL;
if (p1 == NULL)
{
cout << "p1指针为空" << endl;
}
int* p2 = nullptr;
if (p2 == nullptr)
{
cout << "p2指针为空" << endl;
}
system("pause");
return 0;
}
(3) new
和 delete
(动态内存管理)
作用:
- 用于在堆区(Heap)动态分配内存。
- 可以用于分配单个变量,也可以用于分配数组。
示例
#include <iostream>
using namespace std;
int main() {
// 1、动态分配变量的内存
int* p = new int; // 在堆区上分配一个 int 变量
*p = 42; // 赋值
cout << *p << endl; // 输出 42
delete p; // 释放内存
// 2、分配数组的内存
int* arr = new int[5]; // 分配 5 个 int 元素
for (int i = 0; i < 5; i++)
{
arr[i] = i * 10;
cout << arr[i] << " ";
}
cout << endl;
delete[] arr; // 释放数组内存
system("pause");
return 0;
}
注意:
- 用
new
分配单个变量的内存时,使用delete
释放内存。 - 用
new[]
分配数组的内存时,使用delete[]
释放内存。
(4)函数指针
作用:
指向函数的指针,用于回调、动态函数调用。
示例:
#include <iostream>
using namespace std;
void greet()
{
cout << "Hello, C++!" << endl;
}
int main() {
void (*p)() = greet; // 定义函数指针
p(); // 通过指针调用函数
system("pause");
return 0;
}
四、 指针的使用案例
(1)指针与数组
示例——指针遍历数组:
#include <iostream>
using namespace std;
int main() {
int arr[] = { 1, 2, 3, 4, 5 };
int* p = arr; // 数组名本身就是指针
for (int i = 0; i < 5; i++)
{
cout << *(p + i) << " "; // 访问数组元素
}
cout << endl;
system("pause");
return 0;
}
(2) 指针与函数
示例——通过指针修改变量的函数:
#include <iostream>
using namespace std;
void modify(int* p)
{
*p = 20;
}
int main() {
int a = 10;
modify(&a);
cout << a << endl; // 输出 20
system("pause");
return 0;
}
五、 指针的常见错误
(1) 悬空指针(Dangling Pointer)
描述:
指针指向的内存已释放,但仍然访问它。
示例:
#include <iostream>
using namespace std;
int main() {
int* p = new int(10);
delete p; // 释放内存
// cout << *p << endl; // 错误,未定义行为,可导致程序崩溃
system("pause");
return 0;
}
(2) 野指针(未初始化)
描述:
指针变量未被初始化,或者被赋予了一个随意的、无效的地址值。
示例:
#include <iostream>
using namespace std;
int main() {
int* p; // 错误 p 指向未知地址
// cout << *p << endl; // 未定义行为
system("pause");
return 0;
}