Answers:
那是正确的。从C99§6.5.2.1/ 2:
下标运算符[]的定义是E1 [E2]与(*((E1)+(E2)))相同。
没有魔术。这是1-1的当量。与往常一样,在取消引用指针(*)时,您需要确保它指向的是有效地址。
[]
它们称为指针算术的语法糖。混淆初学者的最喜欢的方法是写1[arr]
-而不是arr[1]
-看着他们猜测这意味着什么。
((E1)+(E2))
并将成为具有期望值的(64位)指针。
仅当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]
但是,使用负下标是不寻常的。
int arr[10];
是与前它的其他元件的结构的一部分,arr[-2]
有可能被良好定义的,并且如果它是基于你能确定offsetof
,等等
If one is sure that the elements exist, it is also possible to index backwards in an array; p[-1], p[-2], and so on are syntactically legal, and refer to the elements that immediately precede p[0]. Of course, it is illegal to refer to objects that are not within the array bounds.
尽管如此,您的示例仍然可以帮助我更好地理解它。谢谢!
对我来说听起来不错。但是,您很少有理由合法地需要它。
那可能是arr
指向数组的中间,因此arr[-2]
指向了原始数组中的某些内容而没有超出范围。
我不确定这是否可靠,但我只是阅读了以下有关64位系统(大概是LP64)上的负数组索引的警告:http : //www.devx.com/tips/Tip/41349
作者似乎在说具有64位寻址的32位int数组索引可能导致错误的地址计算,除非将数组索引显式提升为64位(例如,通过ptrdiff_t cast)。我实际上已经看到了他的gcc 4.1.0 PowerPC版本的错误,但是我不知道这是编译器错误(即应根据C99标准工作)还是正确行为(即索引需要转换为64)正确行为的位)?
我知道问题已得到解答,但我无法抗拒分享此解释。
我记得编译器设计原理,假设a是一个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))
i.e. 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))
i.e. 1000 + (-5*2) = 990
它将在位置990返回我对象。通过这种逻辑,我们可以在C语言中访问Array中的负索引。
关于为什么有人要使用否定索引,我在两种情况下使用了它们:
有一张组合数字表,告诉您comb [1] [-1] = 0; 您总是可以在访问表之前检查索引,但是这样,代码看起来更干净并且执行得更快。
在表格的开头放置一个centinel。例如,您想使用类似
while (x < a[i]) i--;
但是您还应该检查是否i
为阳性。
解决方案:使其a[-1]
为-DBLE_MAX
,因此x<a[-1]
始终为假。
#include <stdio.h>
int main() // negative index
{
int i = 1, a[5] = {10, 20, 30, 40, 50};
int* mid = &a[5]; //legal;address,not element there
for(; i < 6; ++i)
printf(" mid[ %d ] = %d;", -i, mid[-i]);
}
somearray-2
是不确定的,除非结果在从开始somearray
到结束为止的1 范围内。