C++-指针

在C++中,指针是至关重要的组成部分。它是C++语言最强大的功能之一,也是最棘手的功能之一。 指针具有强大的能力,其本质是协助程序员完成内存的直接操纵。

指针:特定类型数据在内存中的存储地址,即内存地址。

指针变量的定义语法: 先声明,后赋值:

变量类型 * 指针变量名;       // 声明
指针变量名 = 内存地址值;     // 赋值int num = 10;
int * p;		// 声明
p = #	// 赋值

- 变量类型(如上int)表示,指针(内存地址)指向的内存区域,存放的是整型数据              

- *符号有两种含义:             

- 声明时:*p,表示变量p,是指针变量(存的是内存地址)             

- 使用时:*p,表示取指针p执行内存区域的数据              

- &符号表示取变量内存地址,是一个取内存地址的单目操作符

野指针和空指针

野指针:被声明但未初始化(赋值)的指针。这个指针会指向随机的内存空间,可能导致未知问题。

int * p;    // 声明指针(分配了8字节空间), p是野指针因为未被赋值
*p = 10;    // 将10赋予指针p所指向的空间

*p = 10;是向未知的、随机的4字节内存区域,修改存储值为10

为避免野指针,应养成良好的变成习惯,及时初始化,或将指针置为空指针更为安全

int * p = NULL;
int * p = nullptr;

指针运算

int num = 10;
int *p = #
cout << p << endl;    // 结果:0x20d1ff6e4;
cout << p++ << endl;    // 结果:0x20d1ff6e8

指针进行加减运算的结果,和指针指向内存区域的数据类型有关,以加法为例:

char 类型指针 +1, 地址+1 (字节)

int 类型指针+1, 地址+4(字节)

double 类型指针+1, 地址+8 (字节)

指针运算

数组对象本身记录的是内存地址(第一个元素地址) 可以通过指针运算,完成使用指针存取数组元素。

int v[] = {1, 2, 3, 4, 5};
int *p = v;
*p = 11;                // 赋值数组第一个元素
*(p+1) = 22;            // 赋值数组第二个元素
*(p+2) = 33;            // 赋值数组第三个元素
cout << *p << endl;     // 取数组第一个元素
cout << *(p+1) << endl; // 取数组第二个元素
cout << *(p+2) << endl; // 取数组第三个元素

动态内存分配

动态内存分配:即由程序员手动的进行内存空间的分配、内存空间的释放等内存管理操作。

C++代码中,变量、数组等对象的创建,是由C++自动分配内存的,称之为(自动)静态内存分配。

(自动)静态内存管理,是不会进行内存空间的自动清理的。(无垃圾回收机制) 我们需要手动的管理内存,即手动分配,用完清理。

手动管理方式:

new运算符申请空间,提供该空间的指针(地址)

delete运算符申请的空间,仅用于new申请的空间

建议:写完new后,立刻写delete,然后再写业务逻辑代码

int * p = new int;      // 申请int类型(4字节)空间
int * p = new double;   // 申请double类型(8字节)空间
delete p;               // 删除申请的空间
int * p = new int[5];   // 申请5元素int数组空间
delete[] p;             // 删除申请的5元素数组空间

优势: 手动控制内存,避免内存空间浪费

劣势: 考验程序员水平,用的好效率高,用不好有反效果

new

new运算符用于申请并分配内存空间 并提供指向该空间的指针(内存地址) 基本语法:

new type 申请普通变量空间

new type[n] 申请数组空间

delete

delete运算符用于释放内存 仅可用于new运算符申请的内存区域

基本语法:

delete 指针 删除普通变量空间

delete[] 指针 删除数组空间

数组元素的插入举例:

#include "iostream"
using namespace std;/* 在下标1和3插入数字:11和66 */int main()
{// 示例数组int * pArr = new int[5] {1, 3, 5, 7, 9};// 创建新数组int * pNewArr = new int[7];// 循环新数组,挨个进行元素填充(非插入的位置,填充老数组元素,插入位置填充新元素)int offset = 0;     // 偏移量用来控制新老数组元素的下标对照for (int i = 0; i < 7; i++){if (i == 1){// 走到了下标1,应当执行新元素插入pNewArr[i] = 11;offset++;       // 每插入一个新元素,offset+1continue;} else if (i == 3){// 走到了下标3,应当执行新元素插入pNewArr[i] = 66;offset++;       // 每插入一个新元素,offset+1continue;}// 不是插入位置,从老数组中提取元素放入新数组中// 公式:老数组的元素下标 + offset = 新数组元素下标// 当前循环的i是新数组的元素下标pNewArr[i] = pArr[i-offset];}// 收尾工作delete[] pArr;pArr = pNewArr;// 将新数组的内容输出for (int i = 0; i< 7; i++){cout << pNewArr[i] << ",";}return 0;
}

数组元素的删除举例:

#include "iostream"
using namespace std;int main()
{// 示例数组int * pArr = new int[5] {1, 3, 5, 7, 9};// 创建一个新的数组,将需要保留的复制到新数组中int * pNewArr = new int[4];// 循环去遍历老的数组,将需要的元素放入新数组中(不要的要跳过)for (int i = 0; i < 5; i++){if (i == 2){continue;}if (i > 2){pNewArr[i-1] = pArr[i];}else{pNewArr[i] = pArr[i];}}// 可选delete[] pArr;      // 回收老数组的空间(可选,根据需要来说)// 可选pArr = pNewArr;     // 将老数组的指针指向新数组的内存空间(可选,根据需要)for (int i = 0; i < 4; i++){cout << "新数组的元素是:" << pNewArr[i] << endl;cout << "新数组的元素是:" << pArr[i] << endl;}return 0;
}

指针悬挂:

指针指向区域已经被回收(delete),这种问题称之为:指针悬挂。

不要轻易进行指针之间相互赋值

delete回收空间前,确保此空间100%不再被使用

错误示范:

int main()
{   int * p1 = new int;int * p2 = p1;  // 将p1赋值给p2*p1 = 10;   delete p1;cout << "p2指针记录的是:" << *p2 << endl;return 0;
}

const指针

const是C++关键字,被译为常量,const指针即表示:常量指针。

const用来修饰常量(不可更改),可以配合指针使用 以int为例。

const int * p; 指向常量的指针,即存储值不可变,但指针可修改指向

int * const p = 地址; 常量指针

存储的值可以变 指着不可修改指向 必须初始化指针的地址

const int * const p = 地址; 指向常量的常量指针

存储的值和指针的指向,均不可修改

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

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

相关文章

2024.5组队学习——MetaGPT(0.8.1)智能体理论与实战(下):多智能体开发

传送门&#xff1a; 《2024.5组队学习——MetaGPT&#xff08;0.8.1&#xff09;智能体理论与实战&#xff08;上&#xff09;&#xff1a;MetaGPT安装、单智能体开发》《2024.5组队学习——MetaGPT&#xff08;0.8.1&#xff09;智能体理论与实战&#xff08;中&#xff09;&…

ModelBuilder之GDP空间化——批量值提取

一、前言 前面明确说到对于空间化过程中其实只有两个过程可以进行批量操作,一个是我们灯光指数提取过程和批量进行值提取,这里补充一点,对于灯光指数计算可以实现批量计算总灯光指数和平均灯光指数,综合灯光指数需要用平均灯光指数乘以面积占比求得,面积比就是(DN大于0的…

VS2022通过C++网络库Boost.asio搭建一个简单TCP异步服务器和客户端

基本介绍 上一篇博客我们介绍了通过Boost.asio搭建一个TCP同步服务器和客户端&#xff0c;这次我们再通过asio搭建一个异步通信的服务器和客户端系统&#xff0c;由于这是一个简单异步服务器&#xff0c;所以我们的异步特指异步服务器而不是异步客户端&#xff0c;同步服务器在…

BGP选路规则

配置地址&#xff0c;AS123使用ospf保证通讯&#xff0c;修改接口类型保证ospf学习环回20.0,30.0,100.0 地址时&#xff0c;是以24位掩码学习&#xff0c;R1&#xff0c;R2&#xff0c;R3都处于BGP边界&#xff0c;各自都需要宣告三者的私网环回 1&#xff0c; [R4]ip ip-prefi…

【Qnx 】Qnx IPC通信PPS

Qnx IPC通信PPS Qnx自带PPS服务&#xff0c;PPS全称Persistent Publish/Subscribe Service&#xff0c;就是常见的P/S通信模式。 Qnx PPS的通信模式是异步的&#xff0c;Publisher和Subscriber也无需关心对方是否存在。 利用Qnx提供的PPS服务&#xff0c;Publisher可以通知多…

嵌入式进阶——LED呼吸灯(PWM)

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 PWM基础概念STC8H芯片PWMA应用PWM配置详解占空比 PWM基础概念 PWM全称是脉宽调制&#xff08;Pulse Width Modulation&#xff09…

Arduino下载与安装(Windows 10)

Arduino下载与安装(Windows 10) 官网 下载安装 打开官网&#xff0c;点击SOFTWARE&#xff0c;进入到软件下载界面&#xff0c;选择Windows 选择JUST DOWNLOAD 在弹出的界面中&#xff0c;填入电子邮件地址&#xff0c;勾选Privacy Policy&#xff0c;点击JUST DOWNLOAD即可 …

【脚本篇】---spyglass lint脚本

目录结构 sg_lint.tcl &#xff08;顶层&#xff09; #1.source env #date set WORK_HOME . set REPORT_PATH ${WORK_HOME}/reports puts [clock format [clock second] -format "%Y-%m-%d %H:%M:%S"] #2.generate source filelist #3.set top module puts "##…

qt-C++笔记之QThread使用

qt-C笔记之QThread使用 ——2024-05-26 下午 code review! 参考博文&#xff1a; qt-C笔记之使用QtConcurrent异步地执行槽函数中的内容&#xff0c;使其不阻塞主界面 qt-C笔记之QThread使用 文章目录 qt-C笔记之QThread使用一:Qt中几种多线程方法1.1. 使用 QThread 和 Lambda…

ubuntu server 24.04 网络 SSH等基础配置

1 安装参考上一篇: VMware Workstation 虚拟机安装 ubuntu 24.04 server 详细教程 服务器安装图形化界面-CSDN博客 2 网络配置 #安装 sudo apt install net-tools#查看 ifconfig #修改网络配置 sudo vim /etc/netplan/50-cloud-init.yaml network:version: 2ethernets:en…

飞鸡:从小训练飞行的鸡能飞行吗?为什么野鸡能飞吗?是同一品种吗?今天自由思考

鸡的飞行能力在很大程度上受到其生理结构的限制。尽管鸡有翅膀&#xff0c;但与能够长时间飞行的鸟类相比&#xff0c;鸡的翅膀相对较小&#xff0c;且胸部肌肉较弱。再加上鸡的身体较重&#xff0c;这些因素共同限制了鸡的飞行能力。通常&#xff0c;鸡只能进行短暂的、低空的…

【wiki知识库】01.wiki知识库前后端项目搭建(SpringBoot+Vue3)

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 &#x1f33c;环境准备 想要搭建自己的wiki知识库&#xff0c;要提前搭建好自己的开发环境&#xff0c;后端我使用的是SpringBoot&#xff0c;前端使用的是Vue3&#xff0c;采用前后端分离的技术实现。同时使用了Mysql数…

单工无线发射接收系统

1 绪论 随着无线电技术的发展,通讯方式也从传统的有线通讯逐渐转向无线通讯。由于传统的有线传输系统有配线的问题,较不便利,而无线通讯具有成本廉价、建设工程周期短、适应性好、扩展性好、设备维护容易实现等特点,故未来通讯方式将向无线传输系统方向发展。同时,实现系…

mfc140.dll丢失原因和mfc140.dll丢失修复办法分享

mfc140.dll是与微软基础类库&#xff08;Microsoft Foundation Classes, MFC&#xff09;紧密相关的动态链接库&#xff08;DLL&#xff09;文件。MFC是微软为C开发者设计的一个应用程序框架&#xff0c;用于简化Windows应用程序的开发工作。以下是mfc140.dll文件的一些关键属性…

栈的实现(C语言)

文章目录 前言1.栈的概念及结构2.栈的实现3.具体操作3.1.初始化栈(StackInit)和销毁栈(StackDestory)3.2.入栈(StackPush)和出栈(StackPop)3.3.获得栈的个数(StackSize)、获得栈顶元素(StackTop)以及判空(StackEmpty) 前言 前段时间我们学习过了链表和顺序表等相关操作&#x…

go-zero 实战(4)

中间件 在 userapi 项目中引入中间件。go项目中的中间可以处理请求之前和之后的逻辑。 1. 在 userapi/internal目录先创建 middlewares目录&#xff0c;并创建 user.go文件 package middlewaresimport ("github.com/zeromicro/go-zero/core/logx""net/http&q…

经济寒冬下的黄金跳板:方案、活动、竞标一手掌握

推荐策划人必备的宝藏地产策划资源平台&#xff0c; 订阅浩叫&#xff1a;地产营销策划圈。这个平台简直是地产策划人的百宝箱&#xff0c;里面藏着无数的策划秘籍&#xff0c;等着你来挖掘。 这个平台就像是一个大型的方案库&#xff0c;里面收录了众多知名地产企业的内部资料…

leetcode:计数质数

class Solution { public:// 如果 x 是质数&#xff0c;那么大于 x 的 x 的倍数 2x,3x… 一定不是质数int countPrimes(int n) {vector<int> isPrime(n, 1);int ans 0;for (int i 2; i < n; i) {if (isPrime[i]) {ans 1;if ((long long)i * i < n) {for (int j …

leetcode-55 跳跃游戏

leetcode Problem: 55. 跳跃游戏 思路 假设我们是一个小人&#xff0c;从第一个下标开始&#xff0c;每次经过一个位置&#xff0c;我们就可以根据当前位置的数值nums[i]和位置下标i计算出该位置所能到达的后续位置的最大值rnums[i]i。而这个r之前的区域一定都是可以经过的。…