你如何在 C 中对多维数组进行指针运算?

How do you do Pointer arithmetic with multidimensional arrays in C?

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

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

非常感谢您的提前帮助。

请记住,虽然 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 中遇到的特定问题,并且根据 0 - 9 范围之外的值在任何方向上做出决策 x,y,z 可能会更加困难而不是根据 *(sites + 400) 等符号做出决定(根据您在 OP 中的描述)。

所以总结我的分段错误,我只是在我的跟踪器数组中使用了错误的变量。但是尽管如此,作为一个相当新的程序员,进行这些对话是件好事,感谢您的所有帮助!我很高兴探索了索引和指针的用途。

数组需要

int tracker[totalHops] = {};