「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…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...
C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...
数据库——redis
一、Redis 介绍 1. 概述 Redis(Remote Dictionary Server)是一个开源的、高性能的内存键值数据库系统,具有以下核心特点: 内存存储架构:数据主要存储在内存中,提供微秒级的读写响应 多数据结构支持&…...
