[作者]
常用网名: 猪头三
出生日期: 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等工具, 以减少错误并提升代码质量.