是否可以使用负索引访问二维数组
Is it possible to access two dimensional array with negative indexing?
我试图访问程序中的二维数组,也试图使用负索引(这对我的心理步骤有帮助)。我想对访问数组元素viza[i][j]
使用尽可能简洁的语法。
然而,当我运行程序时,我会遇到分段错误。
#include <iostream>
int main (void)
{
int i,j;
int arr[3][3];
int ** p;
for( i=0; i<3; i++)
{
for(j=0; j<3; j++)
{
arr[i][j] = i+j;
}
}
p = (int **)&(arr[1][1]);
for( i=-1; i<2; i++)
{
for(j=-1; j<2; j++)
{
std::cout << p[i][j] << std::endl;
}
}
return 0;
}
我不想使用类似p[i*something + j]
的东西来访问数组元素。有可能吗?
这很有效(稍后我将更深入地解释):
int (*p)[3] = (int (*)[3])((int *)&arr + 4);
首先。表达式CCD_ 3形成指向与CCD_ 4相同的位置的指针。
然而,我选择了第一种形式以避免可能的反对意见,即&arr[1][1]
形成了一个指针,该指针可能不用于访问子阵列arr[1]
的边界之外。在C中,这是一个有效的反对意见,而在C++中则不太清楚。C++标准在这方面使用了不同的措辞。在任何情况下,我都会通过在单个对象arr
中使用偏移量来完全避免该主题。
之后,它被强制转换,就好像它是一个指向3 int数组的指针一样。(即与&arr[0]
相同的类型)。
我认为可以使用它来访问arr
中的任何int
,尽管我还没有看到很多关于在数组的指针与有效空间和无效空间重叠时使用它的讨论。(我将发布一个新问题…)
据我所知,您试图实现的是,在2D数组中给定一个位置(代码中的[1][1]
),您希望对该位置的邻域执行一些操作。一种可读的方法是如下,我强烈建议它:
int row = 1;
int col = 1;
for (int i = -1; i < 2; i++) {
for (int j = -1; j < 2; j++) {
std::cout << arr[row + i][col + j] << std::endl;
}
}
不过,如果你真的想搞砸指针,还是有办法的。您可以将&arr[1][1]
视为指向长度为3
(arr
的最后一个维度)的数组的指针,它将允许您执行以下操作:
static cont int ROW_LEN = 3; // 3 here is the last dimension of arr
typedef int (*arrRowPtr)[ROW_LEN];
arrRowPtr p = (arrRowPtr)&arr[1][1];
for (int i = -1; i < 2; i++) {
for (int j = -1; j < 2; j++) {
std::cout << p[i][j] << std::endl;
}
}
工作原理:p[i]
与*(p + i)
相同,将i
添加到p
意味着添加i * ROW_LEN * sizeof(int)
,即将位置移动i
行(向前或向后),保留列。*(p + i)
的类型为int[ROW_LEN]
,为了对int*
进行指针运算而衰减,这意味着p[i][j]
将把j * sizeof(int)
添加到p[i]
,也就是说,按j
更改列。
C++标准定义:
5.2.1.1(…)无范围枚举或积分类型。(…)表达式E1[E2](根据定义)与*(((E1)+(E2))相同
因此,它不需要有正积分(不同于根据8.3.4必须为正的数组大小)。当E1是指针,E2是正积分或负积分时,5.7定义了E1+E2。
所以,是的,原则上它应该是有效的。示例:
int a[4][5] = { { 11, 12, 13, 14,15 }, { 21, 22, 23, 24,25 }, { 31, 32, 33, 34,35 }, { 41, 42, 43, 44,45 } };
typedef int (*myarr)[5];
myarr p = (myarr) &a[2][2];
cout << p[0][0] << endl << p[-2][-2]<<endl;
然而,这不是一个好的做法,因为:
- 这可能会造成混乱,因为大多数人都认为指数是正数
- CCD_ 28和CCD_ 29都具有用无符号积分类型定义的CCD_。因此,你的负面索引实践无法轻松转换为更高级的数据结构
- 它适用于多维数组(由于数据的连续性),但它根本不适用于
(int *)&arr + 4
1等数组数组
负索引可以在数组下标中使用,[]
中的索引基本上是指针的偏移量,因此如果您编写:
int array[5]={1,2,3,4,5};
int *arr=&array[2];
int val=arr[-2];
你得到1。
没有简单的方法可以做到这一点。但你可以做一些工作。基本上,你所要做的就是获取指向数组的指针,然后将它们移动到你想要的零位置
#include <assert.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
const int minIndex = -5;
const int maxIndex = 5;
const int size = maxIndex - minIndex;
assert(minIndex < maxIndex);
int arr[size][size];
// initialize the values in the array
for (int i = 0; i < size; ++i) {
for (int j = 0; j < size; ++j) {
arr[i][j] = size*i + j;
}
}
// first get the shifted versions of the inner arrays
int* shiftedInner[10];
for (int i = 0; i < size; ++i) {
shiftedInner[i] = arr[i] - minIndex;
}
// then shift the outer one
int** shifted = &shiftedInner[-minIndex];
// and now you can work with it as if the
// base array were arranged like you want it
printf("%d", shifted[minIndex][minIndex]);
printf("%d", shifted[-3][-4]);
}
这太恶心了,我不建议在生产代码中这样做。但这是可能的。
- 将值从二维数组输出到文本文件
- 在二维数组中查找最小值和最大值?
- 移动二维数组中的字符
- 如何正确填充在堆上分配的二维数组?
- 传递二维数组时出现问题
- 具有随机数的二维数组不会更改
- 如何在C++中获取二维数组中最少的一列数?
- 如何使用用户输入变量制作二维数组?
- C++ 中动态二维数组的访问冲突
- 遍历二维数组的所有子数组
- 将二维数组的所有元素插入到一维数组中
- 在函数中传递二维数组
- 通过访问二维数组实现双线性插值的概念类似于一维数组
- 封装的二维数组与普通版本相比——访问速度
- 是否可以使用负索引访问二维数组
- 从行指针访问二维数组的行索引
- 访问传递给函数的二维数组时出现分段错误
- 如何正确访问指向二维数组的指针的元素
- 删除动态创建的二维数组时出现访问冲突消息
- 访问非托管矢量(C++)中的二维数组