【问题标题】:Modifying a 2D array in a function using pointer arithmetic使用指针算法修改函数中的二维数组
【发布时间】:2019-03-18 16:04:59
【问题描述】:

我编写的用于初始化 2D 网格以实现康威生命游戏的函数存在一些问题。此函数 initialize(bool*, int, int) 使用指针算法来访问我要传递其指针的二维数组中的所有值。

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;
}

逻辑.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 编译器。

【问题讨论】:

    标签: c++ arrays pointers pass-by-reference


    【解决方案1】:

    您不能取消引用指针两次。你只有bool*,没有bool**

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

    【讨论】:

    • i 应该乘以 r,而不是 j。而且没有bool**参与
    • 其实是c,不是r
    • 不,应该是r,而不是cr 代表行,i 计数器代表对行的迭代。每次更改行时,您的记忆都会移动r 位置。这就是为什么您需要将i 乘以rj 负责迭代给定行的单个元素(或 - 迭代给定行的列)。
    • 每次更改行时,都会移动 c 列,因此是 1 行,而不是 r 列。
    • 确实如此。脑放屁发生:>
    【解决方案2】:

    我们来看看你的代码逻辑:

    *(*(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[]

    您现在想要的是访问ith 行和jth 元素。为此,您必须:

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

    • 修正关于感兴趣元素位置的逻辑

    一个简单的解决办法就是改变这个:

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

    到这里:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-13
      • 1970-01-01
      • 2016-01-01
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      • 2017-05-17
      • 2011-07-13
      相关资源
      最近更新 更多