C++语法复习笔记-第6章 c++指针

news2024/11/15 12:29:18

文章目录

  • 1. 计算机内存
    • 1. 储存层次
    • 2. 内存单元与地址
    • 3. 指针定义
  • 2. 左值与右值
    • 1. 数组与指针
    • 1. 概念
  • 3. C++中的原始指针
    • 1. 数组指针与指针数组
    • 2. const pointer 与 pointer to const
    • 3. 指向指针的指针
    • 4.关于野指针
      • 4.1 指向指针的指针
      • 4.2 NULL指针
      • 4.3 野指针
    • 5. 指针的基本运算
      • 5.1 & 操作
      • 5.2 *操作
      • 5.3 ++和--操作
      • 5.4 ++++与----运算符
    • 6. 内存分配
      • 6.1 总览
      • 6.2 heap堆
      • 6.3 分配和回收动态内存的原则
      • 6.4 资源管理方案--RAII
      • 6.5 c++中几种变量的对比
      • 6.6 内存泄漏问题
  • 4 更安全方式使用指针
    • 1. 智能指针
      • auto_ptr
      • unique_ptr
      • shared_ptr
      • weak_ptr

慕课网C++课程

1. 计算机内存

1. 储存层次

在这里插入图片描述

2. 内存单元与地址

在这里插入图片描述
在这里插入图片描述

3. 指针定义

在这里插入图片描述
在这里插入图片描述

2. 左值与右值

1. 数组与指针

在这里插入图片描述

1. 概念

在这里插入图片描述

3. C++中的原始指针

1. 数组指针与指针数组

在这里插入图片描述
在这里插入图片描述

2. const pointer 与 pointer to const

在这里插入图片描述

  • 测试

在这里插入图片描述

  • 数组只是指向了一块字符空间,没有自己真实的地址
    在这里插入图片描述
  • pStr1指向了数组指向的字符的地址,编译器做了优化

在这里插入图片描述

  • pStr2-指针变量本身的地址,为字符数组地址
    在这里插入图片描述
  • pStr3地址指向的字符串内容不能有任何改变
    在这里插入图片描述
  • pStr2指针的内容可以改变,但是与pStr1指针指向的内存一致,因此,虽然pStr1只读,但pStr2改变后,pStr1指向内容还是发生了改变
    在这里插入图片描述

3. 指向指针的指针

在这里插入图片描述

4.关于野指针

4.1 指向指针的指针

在这里插入图片描述
在这里插入图片描述

4.2 NULL指针

在这里插入图片描述
在这里插入图片描述

4.3 野指针

在这里插入图片描述

5. 指针的基本运算

5.1 & 操作

  • 取地址的值,只能做右值,取到地址后,作为一个空间变量,可以赋给一个指针,
  • 但是取特定空间的地址操作不能做左值,即,不能通过取地址操作改变地址
    在这里插入图片描述

5.2 *操作

  • 右值,是取指针指向地址空间上的对象值
  • 左值,是取指针指向的地址空间,可以对地址进行操作
    在这里插入图片描述
    在这里插入图片描述

5.3 ++和–操作

在这里插入图片描述
在这里插入图片描述

  • 不能作为左值,只是一个中间的副本,没有明确的地址
    在这里插入图片描述
    在这里插入图片描述

5.4 ++++与----运算符

在这里插入图片描述

6. 内存分配

6.1 总览

在这里插入图片描述
在这里插入图片描述

6.2 heap堆

在这里插入图片描述

6.3 分配和回收动态内存的原则

在这里插入图片描述

6.4 资源管理方案–RAII

在这里插入图片描述

6.5 c++中几种变量的对比

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6.6 内存泄漏问题

在这里插入图片描述

4 更安全方式使用指针

在这里插入图片描述
在这里插入图片描述

1. 智能指针

auto_ptr

在这里插入图片描述

  • new的对象出了作用域,会自动删除
  • 指针设置为空,用nullptr,NULL是c语言语法,有二意,建议用nullptr对指针设空
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

unique_ptr

在这里插入图片描述

#include "stdafx.h"

#include <memory>   // 智能指针
#include <iostream>
using namespace std;
int main()
{
	// 在这个范围之外,unique_ptr被释放
	{
		auto i = unique_ptr<int>(new int(10));
		cout << *i << endl;
	}

	// unique_ptr
	auto w = std::make_unique<int>(10);
	cout << *(w.get()) << endl;      // 10
	//auto w2 = w; // 编译错误如果想要把 w 复制给 w2, 是不可以的。
	//  因为复制从语义上来说,两个对象将共享同一块内存。

	// unique_ptr 只支持移动语义, 即如下
	auto w2 = std::move(w); // w2 获得内存所有权,w 此时等于 nullptr
	cout << ((w.get() != nullptr) ? (*w.get()) : -1) << endl;       // -1
	cout << ((w2.get() != nullptr) ? (*w2.get()) : -1) << endl;   // 10
    return 0;
}

在这里插入图片描述

shared_ptr

  • 需要一个引用计数的信号量控制

在这里插入图片描述
在这里插入图片描述

weak_ptr

  • 解决循环引用的问题
    在这里插入图片描述
  • 用法示例
  • shared_ptr 内部是利用引用计数来实现内存的自动管理,
  • 每当复制一个 shared_ptr,引用计数会 + 1。当一个 shared_ptr 离开作用域时,引用计数会 - 1。
  • 当引用计数为 0 的时候,则 delete 内存。
// shared_ptr 
	{
		//shared_ptr 代表的是共享所有权,即多个 shared_ptr 可以共享同一块内存。
		auto wA = shared_ptr<int>(new int(20));
		{
			auto wA2 = wA;
			cout << ((wA2.get() != nullptr) ? (*wA2.get()) : -1) << endl;    // 20
			cout << ((wA.get() != nullptr) ? (*wA.get()) : -1) << endl;      // 20
			cout << wA2.use_count() << endl; // 引用计数 :2
			cout << wA.use_count() << endl;                                  // 2
		} // WA2出了作用域,消亡
		//cout << wA2.use_count() << endl;                                               
		cout << wA.use_count() << endl;                                      // 1
		cout << ((wA.get() != nullptr) ? (*wA.get()) : -1) << endl;          // 20
	}
  • move语法的使用
// move 语法
	//将 wAA 对象 move 给 wAA2,意味着 wAA 放弃了对内存的所有权和管理,此时 wAA对象等于 nullptr。
	//而 wAA2 获得了对象所有权,但因为此时 wAA 已不再持有对象,因此 wAA2 的引用计数为 1。
	auto wAA = std::make_shared<int>(30);
	auto wAA2 = std::move(wAA); // 此时 wAA 等于 nullptr,wAA2.use_count() 等于 1
	cout << ((wAA.get() != nullptr) ? (*wAA.get()) : -1) << endl;        // -1
	cout << ((wAA2.get() != nullptr) ? (*wAA2.get()) : -1) << endl;      // 30
	cout << wAA.use_count() << endl;                                     // 0
	cout << wAA2.use_count() << endl;   
  • 循环引用问题
// demo5-11.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <string>
#include <iostream>
#include <memory>
using namespace std;

// 具有shared_ptr指针的两个结构体
struct B;
struct A {
	shared_ptr<B> pb;
	~A()
	{
		cout << "~A()" << endl;
	}
};
struct B {
	shared_ptr<A> pa;
	~B()
	{
		cout << "~B()" << endl;
	}
};

// 具有shared_ptr和weak_ptr指针的两个结构体
struct BW;
struct AW
{
	shared_ptr<BW> pb;
	~AW()
	{
		cout << "~AW()" << endl;
	}
};
struct BW
{
	weak_ptr<AW> pa;
	~BW()
	{
		cout << "~BW()" << endl;
	}
};


// pa 和 pb 存在着循环引用,根据 shared_ptr 引用计数的原理,pa 和 pb 都无法被正常的释放。
// weak_ptr 是为了解决 shared_ptr 双向引用的问题。
void Test()
{
	cout << "Test shared_ptr and shared_ptr:  " << endl;
	shared_ptr<A> tA(new A());       // 1
	shared_ptr<B> tB(new B());       // 1
	cout << tA.use_count() << endl;
	cout << tB.use_count() << endl;
	tA->pb = tB;
	tB->pa = tA;
	cout << tA.use_count() << endl;  // 2
	cout << tB.use_count() << endl;  // 2
}
void Test2()
{
	cout << "Test weak_ptr and shared_ptr:  " << endl;
	shared_ptr<AW> tA(new AW());
	shared_ptr<BW> tB(new BW());
	cout << tA.use_count() << endl;   // 1
	cout << tB.use_count() << endl;   // 1
	tA->pb = tB;
	tB->pa = tA;
	cout << tA.use_count() << endl;   // 1,weak_ptr指向tA,不会对tA的引用计数产生影响
	cout << tB.use_count() << endl;   // 2
} // 当作用域结束后,Aw计数只有1,减一为0后,会正常释放,Aw消亡后,对BW的影响也消除

int main()
{
	Test();
	Test2();

    return 0;
}


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/173993.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 批量插入

文章目录MySQL批量插入10w条数据创建表创建函数创建存储过程调用存储过程MySQL批量插入10w条数据 创建表 创建emp&#xff08;部门&#xff09;表 创建dept&#xff08;员工&#xff09;表 创建函数 创建rand_num函数&#xff0c;随机生成部门编号&#xff0c;保证部门编…

Spark RDD算子

文章目录Spark RDD算子一、RDD 转换算子1、Value 类型(1) mapSpark RDD算子 RDD 方法也叫做RDD算子&#xff0c;主要分为两类&#xff0c;第一类是用来做转换的&#xff0c;例如flatMap()&#xff0c;Map()方法&#xff0c;第二类是行动的&#xff0c;例如&#xff1a;collenc…

Spring Security in Action 第八章 配置授权:api授权

本专栏将从基础开始&#xff0c;循序渐进&#xff0c;以实战为线索&#xff0c;逐步深入SpringSecurity相关知识相关知识&#xff0c;打造完整的SpringSecurity学习步骤&#xff0c;提升工程化编码能力和思维能力&#xff0c;写出高质量代码。希望大家都能够从中有所收获&#…

并查集(Java实现)

基本实现 任务&#xff1a; 维护多个不相交的集合&#xff0c;支持两种操作&#xff1a;合并两个集合&#xff0c;查询一个元素所在的集合。 说明&#xff1a; 维护一个森林&#xff0c;每一棵树都代表一个集合&#xff0c;树根元素为这个集合的代表元。利用数组father[]查询记…

[标准库]STM32F103R8T6 串口的收发

前言 这篇记录一下怎么调用标准库的函数来初始化一个串口&#xff0c;并调库实现发数据和收数据&#xff0c;以及串口收中断的使用。 越往深处学习越感觉其实32就是一个功能更加齐全和强大的MCU&#xff0c;其实跟51没有什么本质上的区别。很多设置的地方都是同质化的。比如需…

JVM知识点整理(整理中)

JVM知识点整理1、JVM与java体系结构1.1、java的体系结构1.2、JVM1.2.1、从跨平台的语言到跨语言的平台1.2.2、常用的JVM实现1.2.3、JVM的位置1.2.4、JDK、JER、JDK1.2.5、JVM的整体结构1.2.6、java代码的执行流程1.2.7、JVM的代码模型1.2.8、JVM的生命周期2、类加载子系统2.1、…

ARM NandFlash 介绍

一、NandFlash 的接口 1、Nand 的型号与命名 (1) Nand 的型号命名都有含义&#xff0c;就拿 K9F2G08 来示例分析一下&#xff1a;K9F 表示是三星公司的 NandFlash 系列。2G 表示 Nand 的大小是 2Gbit&#xff08;256MB&#xff09;。08 表示 Nand 是 8 位的&#xff08; 8 位…

员工入职管理系统|员工管理系统|基于SpringBoot+Vue的企业新员工入职系统

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

SICTF2023 WP

前言 新年前的最后一场比赛&#xff0c;感谢shenghuo2师傅提供的misc和密码的wp&#xff0c;把misc和密码ak了&#xff0c;太强了 web 兔年大吉 源码 <?php highlight_file(__FILE__); error_reporting(0);class Happy{private $cmd;private $content;public function _…

Registration Center

CAP●一致性(Consistency)&#xff1a;所有节点在同一时间具有相同的数据&#xff1b;●可用性(Availability) &#xff1a;保证每个请求不管成功或者失败都有响应&#xff1b;某个系统的某个节点挂了&#xff0c;但是并不影响系统的接受或者发出请求。●分隔容忍(Partition to…

python循环语句

Python循环语句 文章目录Python循环语句一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤1.While循环结构2.While无限循环3.For循环语法4.break语句和continue语句一、实验目的 掌握循环结构的语法 二、实验原理 Python中的循环语句有 for 和 while。 Python…

AcWing蓝桥杯AB组辅导课07、贪心

文章目录前言一、贪心模板题例题1&#xff1a;AcWing 104. 货仓选址&#xff08;贪心&#xff0c;简单&#xff0c;算法竞赛进阶指南&#xff09;分析题解&#xff1a;贪心思路例题例题1&#xff1a;AcWing 1055. 股票买卖 II&#xff08;贪心、状态机&#xff0c;简单&#xf…

[ESP][驱动]GT911 ESP系列驱动

GT911ForESP GT911在ESP系列上的驱动&#xff0c;基于IDF5.0&#xff0c;ESP32S3编写 本库使用面向对象思想编写&#xff0c;可创建多设备多实例 Github&#xff0c;Gitee同步更新&#xff0c;Gitee仅作为下载仓库&#xff0c;提交Issue和Pull request请到Github Github: h…

具体芯片的I2C_Adapter驱动分析

具体芯片的I2C_Adapter驱动分析 文章目录具体芯片的I2C_Adapter驱动分析参考资料&#xff1a;一、 I2C控制器内部结构1.1 通用的简化结构1.2 IMX6ULL的I2C控制器内部结构二、 I2C控制器操作方法三、 分析代码3.1 设备树3.2 驱动程序分析致谢参考资料&#xff1a; Linux内核真正…

03_筛选标记2.0版和3.0版FIND及ColorIndex

文章目录2.0版工作簿筛选标记筛选sheet标记取消筛选标记3.0版ColorIndex 下标代码特别鸣谢,大佬的分享FIND方法的使用2.0版 工作簿筛选标记 Option Explicit Sub 自动筛选()Dim Town As StringDim wsh As WorksheetCall 初始化 初始化表格状态Town InputBox("请输入街…

SLAM笔记——turtlebot传感器ekf实验实验

这里写目录标题实验内容实验准备msg数据类型给uwb和odom增加噪声robot_pose_ekf发布路径实验结果实验内容 本实验将在gazebo仿真环境中使用ekf进行传感器数据融合。本文使用turtlebot3进行实验&#xff0c;turtlebot本身会发布odom和imu。imu的误差可以在urdf文件中进行调整&a…

追梦之旅【数据结构篇】——对数据结构的认知 + 初识时间复杂度和空间复杂度~

详解C语言函数模块知识(下篇&#xff09;&#x1f60e;前言&#x1f64c;浅谈数据结构~&#x1f64c;1、什么是数据结构&#xff1f;(ˇˍˇ) 想&#xff5e;2、什么是算法&#xff1f;ˇˍˇ) 想&#xff5e;3、数据结构和算法的重要性&#x1f60a;4、如何才能学好数据结构呢…

初识 NodeJS(基于 Chrome V8 引擎的 JavaScript 运行时环境)

初识 NodeJS&#xff08;基于 Chrome V8 引擎的 JavaScript 运行时环境&#xff09;参考描述NodeJSNodeJS 可以做什么&#xff1f;特点用武之地获取检测运行JavaScript 运行时环境JavsScript 引擎浏览器中的 JavaScript 运行时环境Chrome 浏览器运行时环境NodeJS 中的 JavaScri…

【着色器实现海面效果_菲尼尔/Unlit/Transparent】

1.水体颜色 2.反射,水面波纹流动 3.折射、水底、水底透明度和折射 4.焦散,在水底接近岸边的水域 5.岸边泡沫,水花接近岸边的泡沫 6.水体运动,顶点动画 用灯光模式是Light Model :Unilt Render Type:Transparent 获取水面深度 利用这个节点,从深度图获取世界空间的位…

如何做流程图?这几个实用的制作流程图方法分享给你

说到流程图的制作&#xff0c;相信大家都并不陌生&#xff0c;在日常的工作和学习中&#xff0c;我们都会根据需求接触到各种各样的流程图&#xff0c;有时还要自己动手绘制流程图并使用&#xff0c;但你是否会因为不会绘制流程图而感到苦恼呢&#xff1f;没关系&#xff0c;今…