指针下标从负值开始

时间:2018-07-17 20:36:24

标签: c arrays pointers

0

我们知道在上述情况下,行从nrow-1开始并以0结尾,列从ncol-1开始并以-4结尾。但是如何让行从nrow+3-4结束,又让列从ncol+3#include <stdio.h> #include <stdlib.h> float *vector(int nl, int nh){ /* allocate a float vector with subscript range v[nl..nh] and initializing this vector, eg. vector[nl..nh]=0.0 */ float *v; int i,NR_END=0; v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float))); for (i=0;i<(nh-nl+1+NR_END);i++) v[i]=0.0; return v-nl+NR_END; } int main(int argc, char *argv[]) { int i,nrow=5, row1, row2; float *v; row1=-4; row2=nrow+3; v = vector(row1,row2); for (i=-4;i<(nrow+4);i++) { v[i]=(float)i; printf("v[%d]=%f\n",i,v[i]); } exit(0); } 结束呢?

补充代码:

 v[-4]=-4.000000
 v[-3]=-3.000000
 v[-2]=-2.000000
 v[-1]=-1.000000
 v[0]=0.000000
 v[1]=1.000000
 v[2]=2.000000
 v[3]=3.000000
 v[4]=4.000000
 v[5]=5.000000
 v[6]=6.000000
 v[7]=7.000000
 v[8]=8.000000

如果我运行上面的代码,它将得到正确的答案:

{{1}}

3 个答案:

答案 0 :(得分:1)

严格来说,您不能在数组的开始或结尾之前建立索引。但是,您可以使数组大于预期的大小,并将起始指针放在中间的某个位置:

int nrow = 5, ncol = 5, pre = 4, post = 4;
int i,j;
float **ptr;

ptr = malloc((nrow+pre+post)*sizeof(float*));
for (i=0;i<nrow+pre+post;i++)
    ptr[i] = malloc((ncol+pre+post)*sizeof(float));
    ptr[i] += pre;   // move up start of column pointers
}
ptr += pre;  // move up start of row pointer

/*initialize*/
for (i=0;i<nrow;i++) {
    for (j=0;j<ncol;j++) {
        ptr[i][j]=0.0;
    }
}

请注意,为每个列分配的列仅分配一次,而不是在第一列中分配。按照您的方式,第一列之后的内容均不指向任何内容。

现在,您可以安全地从-4到max + 3访问索引。

要清理:

ptr -= pre;
for (i=0;i<nrow+pre+post;i++)
    ptr[i] -= pre;
    free(ptr[i]);
}
free(ptr);

答案 1 :(得分:1)

假设您的数组有7个元素,其布局如下:

+-----+-----+-----+-----+-----+-----+-----+
|     |     |     |     |     |     |     |
+-----+-----+-----+-----+-----+-----+-----+

如果指针指向数组的第一个元素,则可以将其索引为:

p
|
v
+-----+-----+-----+-----+-----+-----+-----+
|     |     |     |     |     |     |     |
+-----+-----+-----+-----+-----+-----+-----+
p[0]  p[1]  p[2]  p[3]  p[4]  p[5]  p[6]  

如果指针指向数组中间的元素,则可以使用负值对其进行索引。

                  p
                  |
                  v
+-----+-----+-----+-----+-----+-----+-----+
|     |     |     |     |     |     |     |
+-----+-----+-----+-----+-----+-----+-----+
p[-3] p[-2] p[-1] p[0]  p[1]  p[2]  p[3]  

如果指针指向最后一个元素之后的一个元素,则只能使用负值对其进行索引。

                                          p
                                          |
                                          v
+-----+-----+-----+-----+-----+-----+-----+
|     |     |     |     |     |     |     |
+-----+-----+-----+-----+-----+-----+-----+
p[-7] p[-6] p[-5] p[-4] p[-3] p[-2] p[-1] 

先兆指向第一个元素之前的任何内容都是无效的。因此,无论指针指向元素的有效范围内的哪个位置,有效索引都不能小于-7或大于6。

出现问题

  

但是如何让行从-4开始并以nrow+3结尾,又如何使列从-4开始并以ncol+3结尾?

您不能。如果指针指向数组的第5个元素,则可以使用-4作为有效索引,但是结束条件将为nrow-4 / ncol-4nrow + <some number> / ncol + <some number>将永远不是正确的结束索引。

float** ptr1 = &(5-th row of the array);
for ( int i = -4; i < nrow - 4; ++i )
{
   // OK to use ptr1[i];
   float* ptr2 = &(5-the element/column of the row)
   for ( int j = -4; j < ncol - 4; ++j )
   {
      // OK to use ptr2[j];
   }
}

答案 2 :(得分:0)

您可以执行类似的操作,但我认为您无法访问偏移量这样的列,您需要指向每一行。

main()
{

    int nrow,ncol;
    int i,j;
    float **ptr;
    float *p;

/*allocation*/
    nrow=5;ncol=7; 
    ptr=(float **) malloc((nrow+7)*sizeof(float*));
    for (i=0; i<nrow+7;i++)
        ptr[i]=(float *) malloc((ncol+7)*sizeof(float));
/*initialize*/
    ptr = &ptr[4];
    for (i=-4;i<nrow+3;i++)
        for (j=-4,p=&ptr[i][4];j<ncol+3;j++)
            p[j]=0.0f;
}