C++学习笔记(十三)——指针

一、 指针的作用

指针(Pointer)是 C++ 中的一种特殊变量,它存储的是另一个变量的内存地址,而不是具体的值。

指针有以下作用

  • 直接操作内存地址,提高效率。
  • 动态内存分配,如 newdelete
  • 数组与字符串的操作,如遍历数组。
  • 函数参数传递,提高性能,避免数据拷贝。
  • 实现数据结构,如链表、树等。

二、 指针的声明、取地址和解引用

(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++ 版本作用
NULLC/C++98传统空指针,实际是 0
nullptrC++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) newdelete(动态内存管理)

作用:

  • 用于在堆区(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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奕天者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值