我编写的用于初始化2D网格以实现Conway的《人生游戏》的函数遇到一些问题。此函数 initialize(bool *,int,int)使用指针算法来访问2d数组中我要传递其指针的所有值。
main.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;
}
logic.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)给出2d数组元素(&arr [i] [j])的地址,并且在取消引用后,可以访问arr [i] [j]和更改。如果有人可以指出我的推理中的错误,我将非常感激。我在Code :: Blocks中使用GNU GCC编译器。
答案 0 :(得分:0)
您不能两次取消引用指针。您只有bool*
,没有bool**
。
使用*(p+i*c+j)
。
答案 1 :(得分:0)
让我们看一下您的代码逻辑:
*(*(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
,因为例如第三行的第一个元素是{{二维数组的一维表示形式的第1个元素),位置为3*c
。