• C++
  • C++ 指针与引用核心知识学习笔记

  • @ 2025-7-20 20:54:43

C++ 指针与引用核心知识学习笔记

一、指针基础

(一)指针概念与基本使用

指针是存储变量内存地址的变量,通过 &(取地址运算符)获取变量地址,用 *(解引用运算符)访问指针指向的值。

#include <iostream>
using namespace std;

int main() {
    int num = 42;  
    int* ptr = &num;  // ptr 存储 num 的地址,int* 表示“指向 int 类型的指针”
    
    // 输出指针存储的地址(num 的地址)
    cout << "指针 ptr 的值(num 的地址):" << ptr << endl; 
    // 直接输出 num 的地址,效果和上面一样
    cout << "num 的地址:" << &num << endl; 
    // 解引用 ptr,访问 ptr 指向的变量的值(即 num 的值)
    cout << "指针 ptr 解引用后的值(num 的值):" << *ptr << endl; 
    // 直接访问 num 的值
    cout << "直接访问 num 的值:" << num << endl; 

    // 通过指针修改 num 的值
    *ptr = 100; 
    cout << "通过指针修改后,num 的值:" << num << endl; 

    return 0;
}

(二)指针操作数组

数组名本质是指向数组首元素的指针,利用指针算术运算(+-)可遍历数组,[] 下标运算等价于指针解引用(如 arr[2] 等价于 *(arr + 2) )。

#include <iostream>
using namespace std;

int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    // arr 是数组首元素地址,ptr 指向数组首元素
    int* ptr = arr; 

    // 用数组名遍历(下标法)
    cout << "下标法访问数组:" << endl;
    for (int i = 0; i < 5; i++) {
        // arr[i] 等价于 *(arr + i)
        cout << "arr[" << i << "] = " << arr[i] << endl; 
    }

    // 用指针遍历(指针算术运算)
    cout << "\n指针法访问数组:" << endl;
    for (int i = 0; i < 5; i++) {
        // *(ptr + i) 访问指针偏移 i 后的元素
        cout << "ptr[" << i << "] = " << *(ptr + i) << endl; 
    }

    return 0;
}

二、动态内存分配(new/delete)

C++ 用 new 动态分配内存,delete 释放内存,避免内存泄漏。

(一)动态分配单个变量

#include <iostream>
using namespace std;

int main() {
    // new int 分配一块 int 大小的内存,返回其地址给 ptr1
    int* ptr1 = new int; 
    // 解引用赋值
    *ptr1 = 100; 
    cout << "动态分配变量的值:" << *ptr1 << endl; 

    // 释放内存,避免泄漏
    delete ptr1; 
    // 置空指针,防止野指针
    ptr1 = nullptr; 

    return 0;
}

(二)动态分配数组

#include <iostream>
using namespace std;

int main() {
    // new int[5] 分配能存 5 个 int 的数组,返回首元素地址
    int* arr = new int[5]; 
    for (int i = 0; i < 5; i++) {
        // 初始化数组元素
        arr[i] = i * 10; 
    }

    cout << "动态数组内容:";
    for (int i = 0; i < 5; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;

    // 释放数组内存,[] 表示释放数组
    delete[] arr; 

    return 0;
}

三、指针与函数

(一)值传递(无法修改实参)

直接传变量值,函数内修改是“局部拷贝”,不影响外部实参。

#include <iostream>
using namespace std;

// 值传递:a、b 是实参的拷贝
void swap(int a, int b) {
    int temp = a;
    a = b;
    b = temp;
    // 这里交换的是拷贝,不影响 main 里的 x、y
}

int main() {
    int x = 10, y = 20;
    cout << "交换前:x = " << x << ", y = " << y << endl;
    // 传值调用,swap 内修改不影响外部
    swap(x, y); 
    cout << "交换后:x = " << x << ", y = " << y << endl; 
    return 0;
}

(二)指针传递(修改实参)

传变量地址,函数内通过解引用可直接修改外部实参。

#include <iostream>
using namespace std;

// 指针传递:a、b 是实参地址的拷贝
void swap2(int* a, int* b) {
    int temp = *a; 
    *a = *b; 
    *b = temp; 
}

int main() {
    int x = 10, y = 20;
    cout << "交换前:x = " << x << ", y = " << y << endl;
    // 传地址,&x、&y 是实参地址
    swap2(&x, &y); 
    cout << "交换后:x = " << x << ", y = " << y << endl; 
    return 0;
}

(三)返回指针(需谨慎)

函数可返回动态分配内存的指针,但需注意手动释放,避免泄漏。

#include <iostream>
using namespace std;

// 创建动态数组并返回指针
int* createArray(int size) {
    // 动态分配 size 个 int 的数组
    int* arr = new int[size]; 
    for (int i = 0; i < size; i++) {
        // 初始化元素
        arr[i] = i; 
    }
    // 返回数组首地址
    return arr; 
}

int main() {
    // 获取动态数组指针
    int* arr = createArray(5); 
    cout << "动态数组内容:";
    for (int i = 0; i < 5; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;

    // 释放内存
    delete[] arr; 

    return 0;
}

四、引用(&)

引用是变量的“别名”,语法简洁,常用于函数参数传递(避免拷贝、修改实参)。

#include <iostream>
using namespace std;

int main() {
    int a = 100;
    // b 是 a 的别名,操作 b 等同于操作 a
    int& b = a; 

    cout << "通过引用 b 访问 a 的值:" << b << endl; 
    // 修改引用即修改原变量
    b = 200; 
    cout << "修改引用后,a 的值:" << a << endl; 

    return 0;
}

(一)引用作为函数参数(修改实参更简洁)

#include <iostream>
using namespace std;

// 引用传递:a、b 是实参的别名
void swap1(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 10, y = 20;
    cout << "交换前:x = " << x << ", y = " << y << endl;
    // 传引用,直接修改实参
    swap1(x, y); 
    cout << "交换后:x = " << x << ", y = " << y << endl; 
    return 0;
}

五、函数指针(进阶)

函数指针存储函数的地址,可通过指针调用函数,常用于回调函数、动态选择逻辑。

#include <iostream>
using namespace std;

// 示例函数:返回两数之和
int func(int a, int b) {
    return a + b;
}

int main() {
    // 定义函数指针 funcPtr,指向“接受两个 int、返回 int”的函数
    int (*funcPtr)(int, int); 
    // 让 funcPtr 指向 func 函数
    funcPtr = func; 

    // 直接调用函数
    cout << "直接调用 func:" << func(1, 2) << endl; 
    // 通过函数指针调用(两种写法等价)
    cout << "通过指针调用 func:" << funcPtr(3, 4) << endl; 
    // 等价写法:解引用指针
    cout << "通过解引用指针调用 func:" << (*funcPtr)(5, 6) << endl; 

    return 0;
}

六、总结

  1. 指针:存储地址,灵活操作内存,需注意野指针、内存泄漏(用 new 就要 delete )。
  2. 引用:变量别名,语法简洁,适合函数传参(避免拷贝、直接修改实参)。
  3. 动态内存new/delete 手动管理内存,数组用 delete[] 释放。
  4. 函数指针:指向函数的地址,可动态选择执行逻辑,常用于设计模式(如回调)。

多练习指针与数组、函数的结合场景,理解内存地址操作,就能掌握 C++ 这一核心能力啦~

0 条评论

目前还没有评论...