c++中的二维数组和指针——如何使用二维矩阵的指针遍历每个元素



作为练习,我想通过拖动两个二维矩阵的指针来定义一个矩阵加法。这是起始

const double A[2][2]={{1,2},{3,4}};
double B[2][2]={{4,3},{2,1}};
const double* a=*A;
double* b=*B;

然而,由于指针仅仅指向每个矩阵中第一个数组的第一个元素,a=*(a +0),我如何遍历每个矩阵的每个元素?这里我只使用指针作为参数

void D2Add(const double*, double*){
...for loop here...
}

这里我只想使用指针作为参数

这样你就会有未定义行为不同的子数组可以放在内存的不同页面/段中,越界访问数组不能保证正常工作。我删除了这句话,试图解释访问子数组越界时可能出现的陷阱,因为我现在找不到一个很好的描述。

避免未定义行为的一种方法是通过引用来获取数组:
#include <cstddef>
#include <iostream>
template<std::size_t Y, std::size_t X>
void D2Add(const double(&A)[Y][X], double(&B)[Y][X]) {
for(std::size_t y = 0; y < Y; ++y) {
for(std::size_t x = 0; x < X; ++x) {
B[y][x] += A[y][x];
}
}
}
int main() {
const double A[2][2]={{1,2},{3,4}};
double B[2][2]={{4,3},{2,1}};
D2Add(A, B);
for(auto& inner : B) {
for(auto value : inner) std::cout << value << ' ';
std::cout << 'n';
}
}

输出:

5 5
5 5

这其实是一个很有趣的问题。

正式,你确实只允许访问第一个子数组的元素,而试图访问另一个子数组会导致未定义的行为。

实际上,,您很有可能能够从0循环到4,将数组视为大小为4的1D数组。但是如果可能的话,我建议不要这样做。

希望你已经很好地理解了多维数组是如何在内存中放置的

-在你的函数有一种方法知道数组的维度之前,仅仅通过指针是不可能的。

如前所述,我们还需要向函数传递维度。由于您只想遍历每个元素,因此我将打印每个元素以进行演示。

void D2Add(const double* ptr, int nRow, int nCol) {
for (int i=0; i<nRow; i++) {
for (int j=0; j<nCol; j++) {
std::cout << *(ptr+(i*nCol)+j) << std::endl;
}
}
}