使用指针算法修改函数中的 2D 数组

Modifying a 2D array in a function using pointer arithmetic

本文关键字:2D 数组 函数 修改 指针 算法      更新时间:2023-10-16

我编写的一个函数遇到了一些问题,该函数用于初始化康威生命游戏的2D网格。此函数initialize(bool*, int, int)使用指针算法来访问我正在传递其指针的 2d 数组中的所有值。

主.cpp

#include "logic.cpp"
#include <SFML/Graphics.hpp>
using namespace std;
const unsigned int WIDTH = 640;
const unsigned int HEIGHT = 640;
const int RESOLUTION = 10;
const int rows = (WIDTH/RESOLUTION) - 1;
const int cols = (HEIGHT/RESOLUTION) - 1;
int main()
{
bool curr_gen[rows][cols];
bool next_gen[rows][cols];
bool* curr = &curr_gen[0][0];
bool* next = &next_gen[0][0];
initialize(curr, rows, cols);
/*sf::RenderWindow window(sf::VideoMode(WIDTH, HEIGHT), "Conway's Game of Life");
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
window.display();
}*/
return 0;
}

逻辑.cpp

#include <iostream>
#include <ctime>
void initialize(bool* p, int r, int c)
{
srand(time(NULL));
for(int i=0; i<r; i++)
{
for(int j=0; j<c; j++)
{
if(rand()% 2)
*(*(p+i)+j) = true;
else
*(*(p+i)+j) = false;
}
}
}

我得到的错误都说一元"*"(有"int")的无效类型参数。我看到它的方式,(*(p+i)+j)给出了一个二维数组元素(&arr[i][j])的地址,在取消引用它时,我可以访问arr[i][j]并更改它。如果有人能指出我推理中的错误,我将不胜感激。我在Code::Blocks中使用GNU GCC编译器。

让我们看一下您的代码逻辑:

*(*(p+i)+j) = true;

这试图等同于p[i][j]实际上确实如此。问题是p不是bool[][].这甚至不是bool**.它是一个bool*,它是一个指向bool的指针,它也可能是数组的第一个元素。

请注意,我将要解释的内容T[][]数组有效。它对于动态分配的数组无效,该数组的行也是动态分配的。

我将要解释的是基于这样一个事实,即两个(或三个,或四个...)的维度数组被实现为一个大的,一个维度的数组。如果你有bool[3][3]它实际上是bool[9]的,在访问语法方面有一些好处(以[x][y]访问的形式)。

现在让我们再次看一下您的代码:

for(int i=0; i<r; i++)
{
for(int j=0; j<c; j++)
{
if(rand()% 2)
*(*(p+c)+j) = true;
else
*(*(p+c)+j) = false;
}
}

外部for()循环遍历数组的行。内部for()循环遍历单行的元素。

如果您通过bool**作为p,它实际上会起作用!但你没有。您传递了一个bool*,表示单个数组。您可以利用T[][](二维数组)的实现细节来使用它,就好像它是一个更大的T[]一样。

您现在想要的是访问第i行和第j个元素。为此,您必须:

  • 删除双重取消引用。您正在使用一维数组

  • 修复有关感兴趣元素位置的逻辑

一个简单的解决方法是更改以下内容:

*(*(p+i)+j) = true;

对此:

*(p+i*c+j) = true;

第二个取消引用第i行中的元素(您必须将i乘以c,因为例如第三行的第一个元素是您的二维数组的一维表示的第3*c个元素)和位置j

不能取消两次对指针的引用。你只有一个bool*,没有bool**

使用*(p+i*c+j).