C中是否允许负数组索引?

我只是读了一些代码,发现这个人正在使用arr[-2]访问arr之前的第二个元素,如下所示:

 |a|b|c|d|e|f|g| ^------------ arr[0] ^---------- arr[1] ^---------------- arr[-2] 

这是允许的吗?

我知道arr[x]*(arr + x) 。 所以arr[-2]*(arr - 2) ,这似乎没问题。 你怎么看?

那是对的。 从C99§6.5.2.1/ 2开始:

下标算子[]的定义是E1 [E2]与(*((E1)+(E2)))相同。

没有魔法。 这是一个1-1的等价。 像往常一样,在取消引用指针(*)时,您需要确保指向一个有效的地址。

这只有在arr是指向数组中第二个元素的指针时才有效。 否则,它是无效的,因为你将访问数组的边界之外的内存。 所以,例如,这将是错误的:

 int arr[10]; int x = arr[-2]; // invalid; out of range 

但是这样可以:

 int arr[10]; int* p = &arr[2]; int x = p[-2]; // valid: accesses arr[0] 

然而,使用否定下标是不寻常的。

听起来对我很好。 然而,如果你合法地需要这种情况,那将是一个罕见的情况。

可能是那个arr指向了数组的中间,因此arr[-2]指向原始数组中的某些东西而没有超出范围。

我不确定这是多么可靠,但我只是阅读以下关于64位系统(LP64大概是负数组索引)的警告: http : //www.devx.com/tips/Tip/41349

作者似乎是说,64位寻址的32位int数组索引可能会导致地址计算错误,除非将数组索引明确提升为64位(例如,通过ptrdiff_t转换)。 我实际上已经看到了PowerPC版本的gcc 4.1.0的性质的错误,但我不知道它是一个编译器错误(即应该按照C99标准工作)或正确的行为(即索引需要转换为64位正确的行为)?

我知道这个问题已经回答了,但我无法拒绝分享这个解释。

我记得编译器devise的原理,我们假设一个是int数组,int的大小是2,a的基地址是1000。

a[5]如何工作 – >

 Base Address of your Array a + (index of array *size of(data type for array a)) Base Address of your Array a + (5*size of(data type for array a)) ie 1000 + (5*2) = 1010 

这个解释也是为什么数组中的负指数在C中工作的原因

即如果我访问a[-5]它会给我

 Base Address of your Array a + (index of array *size of(data type for array a)) Base Address of your Array a + (-5 * size of(data type for array a)) ie 1000 + (-5*2) = 990 

它将返回位置990处的对象。通过这个逻辑,我们可以访问C中的数组中的负索引。

关于为什么有人想要使用负面的索引,我已经在两种情况下使用它们:

  1. 有一个组合数字表,告诉你梳[1] [ – 1] = 0; 您可以在访问表之前始终检查索引,但这样代码看起来更干净并且执行速度更快。

  2. 把一个centinel放在一个桌子的开始。 例如,你想使用类似的东西

      while (x < a[i]) i--; 

但是,你也应该检查i是积极的。
解决scheme:使a[-1]-DBLE_MAX ,以使x&lt;a[-1]始终为假。