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

[原创](Modern C++)现代C++的关键性概念: 如何利用多维数组的指针安全地遍历所有元素

[作者]
常用网名: 猪头三
出生日期: 1981.XX.XX
企鹅交流: 643439947
个人网站: 80x86汇编小站
编程生涯: 2001年~至今[共24年]
职业生涯: 22年
开发语言: C/C++、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、
开发工具: Visual Studio、Delphi、XCode、C++ Builder、Eclipse
技能种类: 逆向 驱动 磁盘 文件 大数据分析
涉及领域: Windows应用软件安全/Windows系统内核安全/Windows系统磁盘数据安全/macOS应用软件安全
项目经历: 股票模型量化/磁盘性能优化/文件系统数据恢复/文件信息采集/敏感文件监测跟踪/网络安全检测
专注研究: 机器学习、股票模型量化、金融分析

[序言]
在现代C++编程中, 多维数组的指针操作是一个既基础又关键的概念. 对于需要高效处理数据的场景, 正确使用指针遍历多维数组可以显著提升代码性能, 同时保持良好的可读性和安全性. 然而, 指针操作的复杂性也容易感到困惑, 特别是在边界管理和类型转换上. 

[代码演示]

int main() {

	_setmode(_fileno(stdout), _O_WTEXT);

	// 初始化两个3x4的二维数组, 用于演示.
	int int_MArray_A[3][4] = {
		{1, 2, 3, 4},
		{5, 6, 7, 8},
		{9, 10, 11, 12}
	};

	// pointer_Row 是指向含有4个整数的数组.
	// 即 int_MArray_A 的行指针, 初始指向第一行
	int (*pointer_Row)[4] = int_MArray_A;

	// 将 pointer_Row 指向 int_MArray_A 的最后一行
	pointer_Row = &int_MArray_A[2];

	std::wstring wstr_AllVal{ L"" };
    // 方式1: 手动管理指针遍历多维数组
    // 注意: *auto_pointer_Row 表示多维数组的某一行, *auto_pointer_Row 会被自动转换为指向该行首元素的指针
	// 因此可以用 *auto_pointer_Row + 1, *auto_pointer_Row + 2 ... 这样方式来遍历行内的元素
	for (auto auto_pointer_Row = int_MArray_A;
		auto_pointer_Row != int_MArray_A + 3;
		++auto_pointer_Row)
	{
		for (auto auto_pointer_Col = *auto_pointer_Row;
			auto_pointer_Col != *auto_pointer_Row + 4;
			++auto_pointer_Col)
		{
			wstr_AllVal += std::to_wstring(*auto_pointer_Col);
			wstr_AllVal += L" ";
		}
	}

	// 方式2: 利用 std::begin 和 std::end 简化遍历
	wstr_AllVal = L"";
	for (auto auto_pointer_Row = std::cbegin(int_MArray_A);
		auto_pointer_Row != std::cend(int_MArray_A);
		++auto_pointer_Row)
	{
		for (auto auto_pointer_Col = std::cbegin(*auto_pointer_Row);
			auto_pointer_Col != std::cend(*auto_pointer_Row);
			++auto_pointer_Col)
		{
			wstr_AllVal += std::to_wstring(*auto_pointer_Col);
			wstr_AllVal += L" ";
		}
	}

	std::cin.get();

	return 0;
}

[代码说明]
1. 行指针的定义与操作:
   * int (*pointer_Row)[4]是一个指向含有4个整数的数组的指针, 用于表示int_MArray_A的某一行.
   * 初始时, pointer_Row指向数组的第一行(即int_MArray_A). 随后, 将其重定向到最后一行(&int_MArray_A[2]), 展示了指针可以灵活地定位到任意一行.

2. 遍历多维数组的两种方法:
   * 方式1: 手动管理指针:
     * 外层循环使用auto_pointer_Row从int_MArray_A的起始地址遍历到结束地址(int_MArray_A + 3), 每次递增一行.
     * 内层循环通过*auto_pointer_Row获取当前行的首元素指针, 然后用auto_pointer_Col遍历该行的每个元素(从*auto_pointer_Row到*auto_pointer_Row + 4).

  * 方式2: 利用std::begin和std::end:
    * 外层循环使用std::cbegin(int_MArray_A)和std::cend(int_MArray_A)获取数组的起始和结束迭代器, 无需手动指定行数.
    * 内层循环对每一行使用std::cbegin(*auto_pointer_Row)和std::cend(*auto_pointer_Row)获取该行的迭代器范围.
    * 这种方法利用标准库提供的工具, 自动处理边界, 代码更简洁且更安全, 是现代C++推荐的做法.

[总结]
通过对比两种遍历方式, 可以看到现代C++在保留指针灵活性的同时, 通过标准库提供了更优雅的解决方案. 对于实际开发, 建议优先使用std::begin和std::end等工具, 以减少错误并提升代码质量.


http://www.kler.cn/a/612841.html

相关文章:

  • NoSQL 数据库的适用场景与局限性分析
  • 7.5考研408数据结构散列表专题深度解析
  • Java EE 进阶:MyBatis-plus
  • SQL 复杂查询和性能优化
  • ubuntu 2204键盘按键映射修改
  • nginx部署前端项目(linux、docker)
  • 解锁大语言模型潜力:LangChain,构建AI应用的全新框架
  • Angular由一个bug说起之十五:自定义基于Overlay的Tooltip
  • 数字人分身生成50语种发布会视频技术架构深度解析
  • CTF类题目复现总结-[MRCTF2020]ezmisc 1
  • 网络通信协议浅析:TCP/IP、UDP、HTTP 和 MQTT
  • java项目之基于ssm的亚盛汽车配件销售业绩管理系统(源码+文档)
  • 基于网启PXE服务器的批量定制系统平台(详细版)
  • 推荐系统(十六):基于ESMM的商品召回/推荐系统
  • SpringBoot学习Day1
  • Appium 入门操作指南
  • 地理信息可视化技术大全【WebGIS 技术文档大全】
  • Nginx多域名HTTPS配置全攻略:从证书生成到客户端安装
  • 【矩阵快速幂】P2100 凌乱的地下室|省选-
  • UE4学习笔记 FPS游戏制作31 显示计分板