当前位置: 首页 > news >正文

C++指针使用

C++指针使用

  • 指针定义
  • 指针操作符
  • const指针
    • 数据不可变
    • 地址不可变
    • 地址、数据都不可变
  • 指针与数组
  • 指针与函数
  • 指针与内存管理
    • 分配内存
    • 释放内存
  • 引用
    • 引用作为函数入参
    • 引用作为函数出参
    • 常量引用
    • 使用引用场景
    • 使用指针场景
  • 智能指针
    • std::unique_ptr
    • std::shared_ptr
    • std::weak_ptr

指针定义

数据类型 *指针名; 定义的时候赋初始值,避免野指针

int* p = nullptr;
//int* p = NULL;
//int* p = 0;
cout << "所占存储:" << sizeof(p) << endl;
cout << "地址:" << p << endl;

指针操作符

操作符名称作用
&取地址符获取变量的内存地址
*解引用符访问指针所指向的内存中的值
int* p = nullptr;
int a = 10;
cout << "step1, a=" << a << " ; &a=" << &a << " ; p=" << p << endl;// p存放变量a的地址
p = &a;
cout << "step2, a=" << a << " ; &a=" << &a << " ; p=" << p << " ; *p=" << *p << endl;

const指针

数据不可变

const int* p,指向常量数据的指针(数据不可改)

int a = 10, b = 10, c = 20;const int* p = &a;
cout << "p=" << p << ", *p=" << *p << endl;p = &b;
cout << "p=" << p << ", *p=" << *p << endl;p = &c;
cout << "p=" << p << ", *p=" << *p << endl;// 修改报错
// *p = 100;  
cout << c << endl;
cout << "p=" << p << ", *p=" << *p << endl;c = 100;
cout << c << endl;
cout << "p=" << p << ", *p=" << *p << endl;

地址不可变

int* const p,常量指针(地址不可改)

int a = 10, b = 10, c = 20;int* const p = &a;
cout << "p=" << p << ", *p=" << *p << endl;// 报错,地址不能变
// p = &b;
cout << "p=" << p << ", *p=" << *p << endl;// 修改报错
*p = 100;
cout << c << endl;
cout << "p=" << p << ", *p=" << *p << endl;c = 100;
cout << c << endl;
cout << "p=" << p << ", *p=" << *p << endl;

地址、数据都不可变

const int* const p,两者皆不可改

int a = 10, b = 10, c = 20;const int* const p = &a;
cout << "p=" << p << ", *p=" << *p << endl;// 修改报错
//p = &b;
cout << "p=" << p << ", *p=" << *p << endl;// 修改报错
//*p = 100;

指针与数组

1、int *p = a;int *p = &a[0];

int a[] = { 1, 2, 3, 4, 5 };
int* p = a;
//int* p = &a[0];cout << "*p= " << *p << endl;
cout << "*(p+1)= " << *(p + 1) << endl;
cout << "p[2]= " << p[2] << endl;

指针与函数

void swap(int* a, int* b) {int temp = *a;*a = *b;*b = temp;
}int main()
{int a = 10, b = 20;cout << "交换前:a=" << a << " , &a=" << &a << endl;cout << "交换前:b=" << b << " , &b=" << &b << endl;swap(&a, &b);cout << "交换后:a=" << a << " , &a=" << &a << endl;cout << "交换后:b=" << b << " , &b=" << &b << endl;
}

指针与内存管理

1、 栈上定义的变量不用手动释放,作用域结束就自动回收了
2、堆上定义的变量必须手动delete

分配内存

new关键字

// 在堆分配一个int
int* p = new int;
*p = 42;
cout << "p= " << p << ", *p=" << *p << endl;

释放内存

delete关键字
delete p; // 释放单个对象
delete[] arr; // 释放数组

// 在堆分配一个int
int* p = new int;
*p = 42;
cout << "p= " << p << ", *p=" << *p << endl;delete p;
p = nullptr;cout << "p= " << p << ", *p=" << *p << endl;

引用

引用定义的时候必须初始化,一经绑定不可修改,
理解为变量的别名
类似指针常量,地址不可变

特性引用(Reference)指针(Pointer)
本质变量的别名存储地址的变量
初始化必须在声明时初始化可以延迟初始化
重新绑定❌ 不能重新绑定✅ 可以指向不同对象
空值❌ 不存在空引用✅ 可以为空(nullptr
内存占用通常不额外占用(编译器优化)占用内存(存储地址)
操作符&(声明时)&(取地址),*(解引用)
int a = 10;
int& ref = a;
cout << "step1, a=" << a << ", ref=" << ref << "&a=" << &a << ", &ref=" << &ref << endl;a = 20;
cout << "step2, a=" << a << ", ref=" << ref << "&a=" << &a << ", &ref=" << &ref << endl;ref = 30;
cout << "step3, a=" << a << ", ref=" << ref << "&a=" << &a << ", &ref=" << &ref << endl;

引用作为函数入参

void swap(int& a, int& b) {int temp = a;a = b;b = temp;
}int main()
{int a = 10, b = 20;cout << "交换前,a=" << a << ", b=" << b << endl;swap(a, b);cout << "交换后,a=" << a << ", b=" << b << endl;
}

引用作为函数出参

int& max(int& a, int& b)
{return a > b ? a : b;
}
int main()
{int a = 10, b = 20;cout << "交换前,a=" << a << ", b=" << b << endl;// 返回引用, c与b其实是一个地址int& c = max(a, b);cout << "交换后,a=" << a << ", b=" << b << ", c=" << c << endl;cout << "交换后,&a=" << &a << ", &b=" << &b << ", &c=" << &c << endl;c = 100;cout << "赋值后,a=" << a << ", b=" << b << ", c=" << c << endl;cout << "赋值后,&a=" << &a << ", &b=" << &b << ", &c=" << &c << endl;
}

常量引用

const int &ref = x; 常用于方法入参
不能通过常量引用修改值
可以直接修改原始变量值

int a = 10;
const int& ref = a;cout << "修改前,a=" << a << " ,ref=" << ref << endl;// 不能通过 const 引用修改值
//ref = 20;  // 可以,但 ref 的值也变为 100
a = 100;
cout << "修改后,a=" << a << " ,ref=" << ref << endl;

使用引用场景

  1. 函数入参传递(尤其是大对象)
  2. 函数出参需要修改
  3. 避免拷贝、提高性能
void print(const string &str); 

使用指针场景

  1. 可能为空的情况
  2. 动态内存管理
  3. 需要重新指向不同对象
  4. 实现数据结构(链表、树、图等)
  5. 与 C语言交互(C 语言没有引用)

智能指针

智能指针头文件所有权模型用途
std::unique_ptr<memory>独占所有权单个所有者
std::shared_ptr<memory>共享所有权多个所有者
std::weak_ptr<memory>非拥有引用解决循环引用

std::unique_ptr

  1. 独占所有权:同一时间只能有一个 unique_ptr 指向对象
  2. 不可复制:但可以移动(Move)
  3. 自动释放:析构时自动调用 delete
//std::unique_ptr<int[]> p = std::make_unique<int[]>(10);
std::unique_ptr<int> p = std::make_unique<int>(10);
cout << "修改前,p=" << p << " ,*p=" << *p << endl;*p = 100;
cout << "修改后,p=" << p << " ,*p=" << *p << endl;// 不能复制
// auto p1 = p;// 移动后,p变成空指针
auto p1 = std::move(p);
cout << "移动后,p1 = " << p1 << ", *p1 = " << *p1 << endl;
cout << "移动后,p = " << p << ", *p = " << *p << endl;

std::shared_ptr

  1. 共享所有权:多个 shared_ptr 可以指向同一对象
  2. 引用计数:内部维护引用计数,计数为0时自动释放
  3. 可以复制
std::shared_ptr <int> p1 = std::make_shared<int>(10);
cout << "p1:" << p1.use_count() << endl;{// 复制,共享所有权std::shared_ptr <int> p2 = p1;cout << "p1:" << p1.use_count() << endl;cout << "p2:" << p2.use_count() << endl;// 作用域结束,自动释放
}
cout << "p1:" << p1.use_count() << endl;

std::weak_ptr

解决 shared_ptr 的循环引用问题

  1. 不增加引用计数
  2. 不拥有对象
  3. 必须通过 lock() 转换为 shared_ptr 才能访问对象
std::shared_ptr<int> p = std::make_shared<int>(10);
std::weak_ptr<int> wptr = p;// 检查对象是否还存在
if (auto locked = wptr.lock()) {cout << *locked << endl;  
}
else {cout << "对象已释放" << endl;
}
http://www.dtcms.com/a/503476.html

相关文章:

  • 内江规划建设教育网站国家企业信用公示信息网官网
  • 深入理解 lscpu 命令:如何准确查看 CPU 信息
  • 网站建设需要什么人希腊网站后缀
  • DSync for Mac 文件对比同步工具
  • 「日拱一码」123 内嵌神经网络ENNs
  • C++与易语言开发的基础要求分享
  • 上海市住宅建设发展中心网站建设网站有何要求
  • 广州企业网站建设公司哪家好wordpress改html5
  • ARM 架构核心知识笔记(整理与补充版)
  • 《i.MX6ULL LED 裸机开发实战:从寄存器到点亮》
  • 迈向零信任存储:基于RustFS构建内生安全的数据架构
  • 网站开发公司找哪家帮卖货平台
  • C++ Vector:动态数组的高效使用指南
  • html5微网站漂亮网站
  • C++ 分配内存 new/malloc 区别
  • Respective英文单词学习
  • 网络排错全流程:从DNS解析到防火墙,逐层拆解常见问题
  • 移动端开发工具集锦
  • 使用Nvidia Video Codec(三) NvDecoder
  • 周口规划建设局网站wordpress模板中添加短代码
  • Linux小课堂: 命令手册系统深度解析之掌握 man 与 apropos 的核心技术机制
  • 阿里云做网站官网网站改版的seo注意事项
  • 每日算法刷题Day76:10.19:leetcode 二叉树12道题,用时3h
  • 【OS笔记11】:进程和线程9-死锁及其概念
  • 贪心算法1
  • 服务器搭建vllm框架并部署模型+cursor使用经验
  • Arduino采集温湿度、光照数据
  • 32HAL——外部中断
  • 网站建设会议议程新闻营销发稿平台
  • 【图像处理】CMKY色彩空间