在C语言中,如何使用多维数组进行指针运算?

在C语言中,如何使用多维数组进行指针运算?,c,pointers,multidimensional-array,pointer-arithmetic,C,Pointers,Multidimensional Array,Pointer Arithmetic,如何在多维数组中使用指针?在每个方向上,我将如何用指针算术替换我所做的?我已将我的ptr定义为*位置。我想我需要做这个改变,因为当totalHops>400时,我会出现分段错误。因此,每次显式更改x、y、z一定会导致此错误。上下文:我正在一个逐L逐L的三维空间中移动一个粒子。我有一个随机数生成器来确定粒子在每次随机移动位置时是向左、向右、向上、向下、向后还是向前移动。(注:我已将系统设计为具有周期性边界条件) const int L=10; int N=L*L*L; 总跳数常数=200; int

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

const int L=10;
int N=L*L*L;
总跳数常数=200;
int sites[L][L][L]={};
int x=0,y=0,z=0;
int tracker[N]={};
int*位置;
位置=&站点[0][0][0];

对于(int i=1;i请记住,尽管
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(int)段的顺序大小排列,从
站点所指向的内存位置开始

| | | | | | | | | ...| | | | 
^                        ^
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;
初始化到
站点的开头可以使用
跟踪(或确定)正在查看或修改
3D
数组的哪个元素


这可以很好地应用于您的具体问题,因为跟踪
totalHops
,并根据
0-9
范围以外的值在
x、y、z的任何方向上做出决策可能比根据
*(站点+400)
等符号做出决策更困难(根据您在OP中的描述).

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

数组需要

int tracker[totalHops] = {};

我的建议是:不要。使用正常的数组索引语法。编译器无论如何都会将其转换为指针算术(请记住,对于任何数组或指针
a
和索引
i
,表达式
a[i]
完全等于
*(a+i)
)。至于您遇到的问题,请使用调试器在崩溃发生时捕获它,并在代码中找到它发生的位置。当调试器捕获它并且您在代码中找到它时,请检查所有涉及的变量及其值。我猜您有一些索引超出范围。
int tracker[N]={};
etc不是有效的C。你启用了哪些非标准设置,在哪个编译器上?@Someprogrammerdude谢谢你的建议。我今年2月才开始编程,所以我对调试器几乎没有经验。但我会再次尝试使用调试器。Thanks@asmit98初始值设定项列表必须至少包含一项,因此yes
{0}
是正确的。但是由于
{}
编译,您使用的不是标准C,而是一些扩展。gcc gnu11很可能是gcc的默认模式。感谢您的回答,这是有见地和清晰的演示。我在这种性质的一维问题中使用了指针(只有两个可能的移动方向)。如果我像你上面演示的那样实现指针,避免出现分段错误或错误消息“Abort trap:6”,对内存和程序不会有任何影响吗?@Ryker再次感谢你的帮助help@asmit98-如上所述,
sites[i][j][k]
的表达方式完全等同于
*(sites+ijk)
,因此,是的,逻辑是相同的,选择一种表达式形式或另一种表达式形式的标准是更容易通过编程确定算法中的越界条件。
int tracker[totalHops] = {};