首页 > 解决方案 > 如何在 C 中使用多维数组进行指针运算?

问题描述

如何在多维数组中使用指针?在每个方向上,我将如何用指针算术代替我所做的?我已将我的 ptr 定义为 *location。我认为我需要进行此更改,因为当 totalHops>400 时出现分段错误。因此,每次显式更改 x、y、z 都会导致此错误。上下文:我在一个 L×L×L 的 3D 空间中移动一个粒子。我有一个随机数生成器来确定每次粒子随机移动位置时粒子是否向左、向右、向上、向下、向后或向后移动。(请注意,我已将系统设计为具有周期性边界条件)。

const int L = 10;
int N = L*L*L;
const int totalHops = 200; 
int sites[L][L][L] = {};
int x = 0, y = 0, z = 0;
int tracker[N] = {};
int *location;
location = &sites[0][0][0];
for (int i = 1; i <= totalHops; i++) // the random walk //
    {
        int direction = randomInt(6); // six possible directions to move //
        // along x //
        if (direction == 0) { // move in negative direction //
            x -= 1;
            if (x == -1)
            {
                x = L-1;
            }
        }
        if (direction == 1) { // move in positive direction //
            x +=1;
            if (x == L) 
            {
                x = 0;
            }
        }
        // along y //
        if (direction == 2) { // move in negative direction //
            y -= 1;
            if (y == -1)
            {
                y = L-1;
            }
        }
        if (direction == 3) { // move in positive direction //
            y +=1;
            if (y == L) 
            {
                y = 0;
            }
        }
        // along z //
        if (direction == 4) { // move in negative direction //
            z -= 1;
            if (z == -1)
            {
                z = L-1;
            }
        }
        if (direction == 5) { // move in positive direction //
            z +=1;
            if (z == L) 
            {
                z = 0;
            }
        }
    tracker[i] = sites[x][y][z]; }

非常感谢您提前提供的帮助。

标签: cpointersmultidimensional-arraypointer-arithmetic

解决方案


请记住,尽管C可以容纳 2D、3D、...、nD 数组等数组表示法,但从人类可读性的角度来看,使用它们会更加自然。但在内存中,数组实际上是作为一个连续内存块创建的。例如你的数组:

const int L = 10;
...
int sites[L][L][L] = {0}; //(using {0} is an idiomatic way to init. arrays to all 0

在内存中排列为 10*10*10 连续 sizeof(int) 内存段,从sites.

| | | | | | | | | ...| | | | 
^                        ^
sites + 0                sites + (10*10*10 - 1)*sizeof(int)

由于这个事实,指针数学变得非常简单:

*(sites + 0)   is equivalent to sites[0][0][0]
*(sites + 1)   is equivalent to sites[0][0][1]
*(sites + 2)   is equivalent to sites[0][0][2]
...
*(sites + 10)  is equivalent to sites[0][1][0]
...
*(sites + 100) is equivalent to sites[1][0][0]
...
*(sites + 998) is equivalent to sites[9][9][8]
*(sites + 999) is equivalent to sites[9][9][9]

指针表示法和数组表示法之间的模式变得非常明显,因为添加到数组开头的数字与数组表示法中索引的排列相关。

基于这种基本形式,您可以派生一种使用指针数学来表示多维数组的方法,在您的情况下,使用int *location;初始化到开头sites可用于跟踪(或确定)3D正在查看的数组元素,或修改。

这可以很好地适用于您在该跟踪中的特定问题,并且基于任何方向totalHops范围之外的值做出决策可能比基于诸如(根据您在 OP 中的描述)之类的符号做出决策更困难。 0 - 9x,y,z*(sites + 400)


推荐阅读