「C/C++」C/C++ 指针篇 之 指针运算

| ✨博客主页 | ||
|---|---|---|
| 何曾参静谧的博客 | ||
| 📌文章专栏 | ||
| 「C/C++」C/C++程序设计 | ||
| 📚全部专栏 | ||
| 「VS」Visual Studio | 「C/C++」C/C++程序设计 | 「UG/NX」BlockUI集合 |
| 「Win」Windows程序设计 | 「DSA」数据结构与算法 | 「UG/NX」NX二次开发 |
| 「QT」QT5程序设计 | 「File」数据文件格式 | 「PK」Parasolid函数说明 |
目录
- C++ 指针运算深度解析
- 一、指针运算的基础
- 1. 指针加减整数
- 2. 指针与指针之间的运算
- 3. 指针的解引用与赋值
- 二、指针运算的应用场景
- 1. 数组遍历
- 2. 字符串处理
- 3. 动态内存管理
- 三、指针运算的潜在风险
- 1. 野指针
- 2. 内存泄漏
- 3. 数组越界
- 四、最佳实践
C++ 指针运算深度解析
在C++编程中,指针不仅是内存地址的持有者,更是连接数据与操作的桥梁。指针运算,作为C++编程的一项基本技能,其重要性不言而喻。本文将深入探讨C++中的指针运算,涵盖其基本概念、运算规则、应用场景以及潜在风险。
一、指针运算的基础
指针运算,指的是对指针变量进行的一系列算术操作,这些操作通常基于指针所指向的数据类型的大小。在C++中,指针运算主要包括指针的加减运算、指针与整数的运算以及指针之间的比较运算。
1. 指针加减整数
当对指针进行加减整数运算时,整数会被解释为指针所指向数据类型大小的倍数。例如,若指针指向int类型(通常占4个字节),则对指针加1,实际上是将指针向前移动了4个字节。
int arr[5] = {1, 2, 3, 4, 5};
int* ptr = arr; // ptr 指向数组的第一个元素
ptr++; // ptr 现在指向数组的第二个元素
ptr += 2; // ptr 现在指向数组的第四个元素(因为每次加1都跳过4个字节)
2. 指针与指针之间的运算
两个指针之间的减法运算,其结果是它们之间相隔的元素个数(基于指针所指向的数据类型)。而指针之间的比较运算,则是基于它们在内存中的相对位置。
int arr[5] = {1, 2, 3, 4, 5};
int* p1 = &arr[1]; // 指向数组的第二个元素
int* p2 = &arr[4]; // 指向数组的第五个元素
int diff = p2 - p1; // diff 的值为 3,因为 p2 和 p1 之间相隔三个 int 类型的元素
3. 指针的解引用与赋值
解引用指针(使用*操作符)可以获取指针所指向的数据。而给指针赋值,则是将新的内存地址赋给指针变量。
int a = 10;
int* ptr = &a; // ptr 指向 a 的地址
*ptr = 20; // 通过指针修改 a 的值为 20
二、指针运算的应用场景
指针运算在C++编程中有着广泛的应用,包括但不限于数组遍历、字符串处理、动态内存管理以及数据结构实现等。
1. 数组遍历
数组名在C++中可以被视为指向数组第一个元素的指针,因此可以使用指针来遍历数组。
int arr[5] = {1, 2, 3, 4, 5};
int* ptr = arr;
for (int i = 0; i < 5; ++i) {std::cout << *(ptr + i) << std::endl; // 通过指针遍历数组
}
2. 字符串处理
C++中的字符串(以字符数组的形式表示)可以通过指针进行高效处理。例如,可以使用指针来遍历字符串、查找字符或进行字符串拼接等操作。
char str[] = "Hello, World!";
char* ptr = str;
while (*ptr != '\0') {std::cout << *ptr;++ptr;
}
std::cout << std::endl;
3. 动态内存管理
在C++中,new和delete操作符用于动态地在堆上分配和释放内存。指针运算在这些操作中扮演着重要角色。
int* arr = new int[5]; // 在堆上分配一个包含5个整数的数组
for (int i = 0; i < 5; ++i) {*(arr + i) = i * 10; // 使用指针运算给数组赋值
}
// ... 使用数组 ...
delete[] arr; // 释放数组所占用的内存
三、指针运算的潜在风险
尽管指针运算功能强大,但它也带来了潜在的风险。若不慎使用,可能会导致程序崩溃、内存泄漏或未定义行为等问题。
1. 野指针
野指针是指未初始化或已被释放的指针。若对野指针进行解引用或运算,将导致未定义行为。
int* ptr; // 未初始化的指针(野指针)
*ptr = 10; // 未定义行为,因为 ptr 没有指向有效的内存地址
2. 内存泄漏
若在使用完动态分配的内存后未正确释放,将导致内存泄漏。长时间运行的程序可能会因此耗尽系统资源。
int* ptr = new int(10); // 动态分配内存
// ... 使用 ptr ...
// 忘记删除 ptr,导致内存泄漏
3. 数组越界
指针运算时若未正确检查边界条件,可能会导致数组越界访问。这不仅会破坏数据的完整性,还可能引发程序崩溃。
int arr[5] = {1, 2, 3, 4, 5};
int* ptr = arr;
for (int i = 0; i <= 5; ++i) { // 错误的边界条件(应为 i < 5)std::cout << *(ptr + i) << std::endl; // 当 i = 5 时,将访问数组之外的内存
}
四、最佳实践
为了避免指针运算带来的风险,建议遵循以下最佳实践:
- 初始化指针:在声明指针时立即进行初始化,确保它指向有效的内存地址。
- 避免野指针:在使用指针之前检查其是否为空。若指针可能变为空(例如,在删除动态分配的内存后),请将其设置为
nullptr。 - 正确释放内存:在使用完动态分配的内存后,务必使用
delete或delete[]操作符释放内存。 - 检查边界条件:在进行指针运算时,始终检查边界条件以避免数组越界访问。
- 使用智能指针:C++11引入了智能指针(如
std::unique_ptr和std::shared_ptr),它们能够自动管理内存并减少内存泄漏的风险。在可能的情况下,优先使用智能指针来管理动态内存。
通过遵循这些最佳实践,你可以更安全、更有效地使用C++中的指针运算。

相关文章:
「C/C++」C/C++ 指针篇 之 指针运算
✨博客主页何曾参静谧的博客📌文章专栏「C/C」C/C程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…...
计算机网络网络层笔记
互联网提供的两种服务 1.虚电路服务 2.数据报服务 需要记住的是现在只用第二种也就是数据报服务 网际协议IP 物理层的中断系统:转发器(hub) 链路层的中断系统:交换机 网络层的中断系统:路由器 网络层以上:网关 如上图所示,网关是用来访问其他的网段的一个接口,网关的地…...
长亭那个检测能力超强的 WAF,出免费版啦
告诉你们一个震撼人心的消息,那个检测能力超强的 WAF——长亭雷池,他推出免费社区版啦,体验地址见文末。 八年前我刚从学校毕业,在腾讯做安全研究,看到宇森在 BlackHat 上演讲的议题 《永别了,SQL 注入》 …...
rabbitMQ RabbitTemplate 发送消息
消息发送确认机制 消息发送确认机制:消息由producer发送后,确认其是否到达broker,又是否被exchange转发至对应queue的机制 该机制分为两部分:producer---broker,exchange---queue 前者的实现依靠ConfirmCallback机制…...
本系列是《10万字208道Java经典面试题总结(附答案)》的2024修订版。
公众号 后端学习指南 本系列是《10万字208道Java经典面试题总结(附答案)》的2024修订版。 1、说说跨平台性 我们希望编写好的代码和程序,最好可以在任意平台和环境下运行,而不需要根据不同的平台,编写不同的代码。 比如,我编写的一个博客管理系统,我希望它可以在windo…...
C语言文件基础概念的理解(一)
文件基础概念 为什么有文件? 我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失 了,等再次运⾏程序,是看不到上次程序的数据的,如果要将数据进⾏持久化的保存…...
C++ lambda 匿名函数
看了明仕强老师的课程,C匿名函数也可以很简单 下面请看示例代码: /* lambda表达式学习,测试主函数 */#include <iostream>using namespace std;int main() {printf("Lambda test Demo:\n");//值捕获,值捕获的时候不能修…...
基于python的简单web服务器示例
安装flask flask 简介:是一个用Python编写的Web应用程序框架。 它由 Armin Ronacher 开发,他领导一个名为Pocco的国际Python爱好者团队。 Flask基于Werkzeug WSGI工具包和Jinja2模板引擎。两者都是Pocco项目 新建项目 创建好的效果 pip list 检索 安装…...
02- 模块化编程-006 ADC0808数码显示对比
1、ADC0808 芯片介绍 ADC0808是一款集成的CMOS设备,包含8位模拟至数字转换器、8通道多路复用器和与微处理器兼容的控制逻辑。8位A/D转换器采用逐次逼近作为转换技术。转换器特点包括高阻抗斩波稳定比较器、256R电压分压器、模拟开关树和逐次逼近寄存器。8通道多路复…...
又发现了Mac妙控鼠标的新使用方法
我一直是不爱用妙控鼠标的,因为用起来怪怪的,但是今天发现BettreAndBetter支持妙控鼠标的修改,于是就找出了闲置了许久的妙控鼠标试了一下 优化后的妙控鼠标使用起来就没有任何不适应的地方了,三指按下模拟中键,而且还…...
Webserver(4.6)poll和epoll
目录 pollclient.cpoll.c epollepoll.cclient.c epoll的两种工作模式水平触发边沿触发 poll poll是对select的一个改进 select的缺点在于每次都需要将fd集合从用户态拷贝到内核态,开销很大。每次调用select都需要在内核遍历传递进来的所有fd,这个开销也…...
LVGL 与 QT
LVGL 与 QT LVGL 适用于嵌入式、资源受限设备,尤其是在需要高效图形渲染和小型显示屏的场景下非常合适。它具有轻量级、模块化的特点,适用于内存和计算能力有限的硬件。 Qt 是一个功能强大的跨平台框架,适合开发桌面应用以及较为复杂的嵌入式…...
如何选择最适合的项目管理软件?2024年大厂首选7款工具盘点
选择最适合的项目管理软件对于提升团队效率、优化工作流程至关重要。2024年,各大厂在项目管理上逐渐趋向于使用更加智能化、集成化和协作性的工具。以下是如何选择最适合的项目管理软件,并对2024年大厂首选工具进行盘点。 选择适合的项目管理软件的关键…...
【数据结构】选择排序——选择排序 和 堆排序
选择排序 和 堆排序 一、选择排序选择排序的思路及其代码选择排序的弊端 二、堆排序三、速度对比同时排10000个数同时排100000个数同时拍500000个数堆排 1 亿个数 一、选择排序 选择排序的思路及其代码 选择排序思路很简单 就是经过将数组遍历选择最小值 将最小值位置的数与数…...
P11229 [CSP-J 2024] 小木棍
[CSP-J 2024] 小木棍 题目描述 小 S 喜欢收集小木棍。在收集了 n n n 根长度相等的小木棍之后,他闲来无事,便用它们拼起了数字。用小木棍拼每种数字的方法如下图所示。 现在小 S 希望拼出一个正整数,满足如下条件: 拼出这个数…...
【学习笔记】SAP ABAP——OPEN SQL(一)【SELECT语句】
SELECT语句简介 SELECT <lines> <columns> FROM <db> WHERE <condition>其中代表查询的件数,代表查询的字段名 SELECT SINGLE SELECT SINGLE <cols> FROM <db> WHERE <condition>该语句用于从数据库表中查询单条数据 …...
SQL注入(1)
1.数字型注入 例如PHP代码 “ Select username from users where id”.$_GET[id] 可以注意到,用户的输入ID字段没有任何过滤的,被直接拼接在了SQL查询语句中,由于ID没有被引号包裹ÿ…...
在AI时代,如何解决人的工作岗位被AI替代的问题?
在AI时代,工作岗位被AI替代的问题确实是一个重要的社会课题。随着技术的不断进步,许多传统的工作变得自动化,这带来了效率的提升,但也引发了就业方面的挑战。要应对这一问题,我们可以从以下几方面入手: 促进…...
Linux命令--paste
简介 paste命令用于合并文件行 参数说明 -d: 自定义间隔符,默认为tab -s:串行处理,非并行 示例 将两个文件,按照行合并 demo1.conf内容如下: name domain ip area user password roledemo2.conf内容如下 test t…...
数据结构模拟题[九]
数据结构试卷(九) 一、选择题 (30 分) 1.下列程序段的时间复杂度为( )。 for(i0 ; i<m ; i) for(j0 ; j<t ; j) c[i][j]0 ; for(i0 ; i…...
音频标注:从原理到产业,AI听懂世界的“翻译官”
音频标注:从原理到产业,AI听懂世界的“翻译官” 引言 在人工智能的浪潮中,计算机视觉的“看”和自然语言处理的“读”已广为人知,而让机器学会“听”——理解并解析复杂的声音世界,正成为新的前沿。这一切的基石&…...
零代码也能构建智能登录系统?Dify工作流让你告别繁琐的前端开发
零代码也能构建智能登录系统?Dify工作流让你告别繁琐的前端开发 【免费下载链接】Awesome-Dify-Workflow 分享一些好用的 Dify DSL 工作流程,自用、学习两相宜。 Sharing some Dify workflows. 项目地址: https://gitcode.com/GitHub_Trending/aw/Awes…...
SaaS级AI员工系统源码商用版,多租户+计费系统+API分销,一套源码搞定
温馨提示:文末有资源获取方式最近“龙虾AI”的热度居高不下,到处都在讨论如何“养龙虾”。但观察下来发现,这类应用对普通用户而言技术门槛还是偏高,部署、配置、调试都需要专人跟进,最终往往沦为摆设。源码获取方式在…...
流注放电,COMSOL放电仿真,等离子体仿真,棒板电极,空气流注,流注放电,需要拿去参考
流注放电,COMSOL放电仿真,等离子体仿真,棒板电极,空气流注,流注放电,需要拿去参考。流注放电这玩意儿在高压设备里常见得跟小区门口的便利店似的。实验室里整了个棒板电极结构,空气里突然窜出条…...
PTA编程题‘Person抽象类’避坑指南:变量命名冲突、多态指针数组与输出格式化的那些坑
PTA编程题‘Person抽象类’避坑指南:变量命名冲突、多态指针数组与输出格式化的那些坑 在C面向对象编程的实战中,抽象类和派生类的设计看似简单,却暗藏诸多陷阱。许多初学者在完成PTA/LeetCode这类编程题时,往往因为一些看似微不足…...
农业气象监测系统—实时感知・远程管控・智能预警
在农业现代化向纵深推进的当下,气象数据已成为农业生产的 “核心指挥棒”。烟台中盾信息科技有限公司(下称 “烟台中盾科技”)紧扣农业农村发展需求,以物联网、大数据技术为基石,打造农业气象监测系统,构建…...
如何快速上手uesave-rs:虚幻引擎存档编辑的终极指南
如何快速上手uesave-rs:虚幻引擎存档编辑的终极指南 【免费下载链接】uesave 项目地址: https://gitcode.com/gh_mirrors/ue/uesave 还在为无法修改心爱游戏的存档而烦恼吗?想要自定义游戏体验却不知从何下手?uesave-rs这款强大的Rus…...
小红书数据采集系统深度探索:从技术原理到实战落地
小红书数据采集系统深度探索:从技术原理到实战落地 【免费下载链接】XiaohongshuSpider 小红书爬取 项目地址: https://gitcode.com/gh_mirrors/xia/XiaohongshuSpider 在当今数据驱动的时代,小红书作为内容丰富的社交平台,其数据价值…...
给嵌入式新手的Cortex-M0内核超详细图解:从寄存器到中断,一篇搞定STM32/GD32入门
给嵌入式新手的Cortex-M0内核超详细图解:从寄存器到中断,一篇搞定STM32/GD32入门 刚拿到STM32开发板时,看着密密麻麻的引脚和上百页的芯片手册,我完全不知道从哪里开始。直到导师指着原理图说:"把芯片想象成一个忙…...
用了Trae写业务系统,为什么上线前总要手动补依赖和权限?
发版前夜,测试跑穿才发现前端字段跟后端对不上,改到凌晨三点才勉强收口。这种场景在引入 AI Coding 后并不罕见,不少团队用了 Trae 写业务系统,速度是上去了,可上线前总得花半天专门查安全漏洞和依赖冲突。大家原指望 …...
