• C++
  • C++ 指针教程:从基础到进阶

  • @ 2025-10-29 10:23:05

C++ 指针教程:从基础到进阶

一、指针基础概念

1.1 什么是指针?

指针是存储变量内存地址的变量,通过间接访问内存数据实现高效操作^^1^^。例如:

int a = 10; int* p = &a; // p 存储变量a的地址 cout << *p; // 输出10(通过指针访问a的值)

1.2 指针声明与初始化

声明格式:数据类型* 指针变量名(如 int* ptr)^^2^^

初始化方式:

int* p1 = nullptr; // 空指针 int* p2 = new int(20); // 动态分配内存

1.3 指针运算符

& 取地址:int* p = &a;

  • 解引用:*p = 20;

-> 访问成员:struct Student s; s_ptr->age = 18;

二、指针核心操作

2.1 指针运算

指针加减以数据类型大小为步长:

int arr^3^ = {1, 2, 3}; int* p = arr; p++; // p 指向arr^1^ cout << *p; // 输出2

2.2 指针与数组

数组名即首元素地址:

int arr = {1, 2, 3, 4, 5}; int* p = arr; cout << *(p + 2); // 输出3

2.3 指针与字符串

字符串本质是字符数组:

char str[] = "Hello"; char* p = str; while (*p) { cout << *p++; } // 逐字符输出

三、指针高级应用

3.1 动态内存管理

int* p = new int; // 分配10个int空间 delete[] p; // 释放内存

3.2 函数指针

void print(int x) { cout << x; } void (*func_ptr)(int) = print; // 函数指针声明 func_ptr(42); // 调用函数

3.3 多态实现

class Animal { public: virtual void sound() = 0; }; class Dog : public Animal { void sound() override { cout << "Woof!"; } }; Animal* animal = new Dog(); animal->sound(); // 输出 "Woof!"

四、指针安全实践

避免悬垂指针:释放内存后立即置空

delete p; p = nullptr;

使用智能指针(C++11+)

std::unique_ptr ptr = std::make_unique(42);

常量指针与指针常量

const int* p1 = &a; // 指向常量的指针 int* const p2 = &a; // 指针常量

五、常见问题解答

Q:指针与引用的区别? A:指针是变量,存储地址;引用是别名,必须初始化且不可改变指向。

Q:如何避免内存泄漏? A:优先使用智能指针,或严格遵循谁分配谁释放的原则。

Q:指针越界会发生什么? A:可能覆盖其他数据或导致程序崩溃,需确保指针操作在有效范围内。 (AI生成)

1 条评论

  • @ 2025-10-29 10:23:53

    C++指针教程:核心概念与实战应用

    一、指针基础:内存地址的钥匙

    指针的本质 指针是存储变量内存地址的变量,通过取址符(&)获取地址,取值符(*)访问地址内容。

    int x = 10; int* p = &x; // p存储x的地址 cout << *p; // 输出10

    指针类型与运算

    指针类型决定步长(如int移动4字节,char移动1字节)。

    加减运算基于类型大小:p + 1指向下一元素,p - 1指向上一个元素。

    示例:访问数组元素

    int arr[5] = {1, 2, 3, 4, 5}; int* p = arr; // p指向arr[0] cout << *(p + 2); // 输出3

    二、指针进阶:函数与动态内存

    函数指针 函数指针指向函数入口,需用括号声明类型:

    int add(int a, int b) { return a + b; } int (*funcPtr)(int, int) = &add; // 函数指针 cout << funcPtr(3, 4); // 输出7

    动态内存管理

    new/delete:分配/释放堆内存。

    示例:动态数组

    int* arr = new int[5]; // 分配5个int delete[] arr; // 释放内存

    三、常见陷阱与最佳实践

    优先级问题 p++等价于(p++)(先移动指针后取值),(*p)++等价于(*p)后自增。

    int x = 10; int* p = &x; cout << *p++; // 输出10,p指向下一地址

    指针与数组的等价性 数组名是首元素地址,arr[i]等价于*(arr + i)。

    int arr[3] = {1, 2, 3}; cout << *(arr + 1); // 输出2

    避免野指针 指针未初始化或释放后仍使用会导致未定义行为。

    int* p = nullptr; // 初始化为nullptr if (p != nullptr) { // 安全使用 }

    四、实战案例:字符串处理

    删除字符串中指定字符:

    void delchar(char* str, char c) { while (*str) { if (*str == c) { strcpy(str, str + 1); // 覆盖字符 } str++; } } // 调用示例 char s[] = "student"; delchar(s, 't'); // 输出"suden"

    五、总结

    核心作用:指针实现动态内存、函数回调、高效数组操作。

    关键操作:取址(&)、取值(*)、指针运算。

    安全建议:初始化指针、释放内存、避免越界。 (AI生成)

    • 1