如何使用负索引的(2d)数组?

时间:2011-08-26 06:26:40

标签: c++ c arrays

在1D中,您可以通过以下方式模拟x坐标:

int temp[1000];
int *x = a+500;

我们现在怎样才能有网格? (类似于a[10][-13]。)

6 个答案:

答案 0 :(得分:2)

不要将数学与C / C ++中的数组维度混淆,这些是不同的东西。如果您有一个索引为-500到500的数学矩阵,则使用索引为0到1000的C数组来存储它。

但是您可以使用负索引访问数组,只要您确保不访问数组越界。例如:

int arr[1000];
int* ptr = &arr[499];
printf("%d", ptr[-100]);

2D数组以相同的方式工作,尽管严格来说你仍然无法访问超出边界的子数组并期望最终在相邻的数组中,这是C / C ++中未定义的行为。但在现实世界的实现中,静态2D数组总是使用相邻的存储单元进行分配,因此无论C标准如何,人们通常都可以安全地假设它们。

答案 1 :(得分:2)

您可以轻松地将-ve和+ ve整数转换为只是+ ve整数作为数组的索引,因为您无法使用-ve indexes。

以下是

if (index < 0)
then index = -index * 2 - 1
else index = index * 2

即。 -ve索引使用奇数,+ ve使用偶数。 0保持为0.

答案 2 :(得分:1)

您只需自己计算偏移量,例如

int grid[400]; // twenty by twenty grid, origin at (10, 10)

int get_grid_value(int x, int y)
{
  return grid[20*(x + 10) + (y + 10)];
}

当然在实际代码中你不应该使用那么多魔术数字

答案 3 :(得分:0)

首先,这仅在为阵列分配的内存是连续的时才有效。然后你可以通过

找出数组的“中间点”
int temp[5][5];
int *a = temp[2] + 2;

或者,更笼统地说

int len
int *temp = malloc(len * len * sizeof(int));
int *a = temp + (len/2)*len + len/2;

答案 4 :(得分:0)

如果您想使用数组模拟几何体......您可以执行类似

的操作

有一个具有最大点数的变量,并指定一个指向中间值的指针。因此,使用该指针可能会产生负面的差异。

示例程序。

int main() {
    int c[10000];
    int *a = &c[5000];
    for(int i=-5000;i<5000;i++)
            a[i] = i;
    for(int i=-5000;i<5000;i++)
            cout<<a[i]<<" ";
    cout<<endl;
    return 0;
}

希望这对你有帮助.. 要以更恰当的方式使用它,您可以拥有一个内部管理它的类。或者你可以拥有你的模板。

答案 5 :(得分:0)

我不确定你能用一个简单的二维数组做到这一点而不调用未定义行为的gremlins,但你可以把它设置为一个指针数组。创建一个指向int的指针数组,然后设置指向数组中间的指针;它为您提供第一个维度的签名索引。然后将指针数组的每个元素设置为指向int数组,并将每个元素前进指向该数组的中间位置;它为您提供第二维的签名索引。您可以使用与实际二维数组相同的arr[x][y]语法,但第二个[]适用于实际指针,而不是一个衰减为指针的数组。

如果这些数组中的任何一个分配了malloc(),则必须将原始指针传递给free()

如果有足够的兴趣,我会稍后尝试发布一些代码。

顺便说一下,我完全不相信这是值得的。你可以用普通的基于0的数组轻易伪造所有这些,但代价是一点点语法糖。