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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3473675/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:10:28  来源:igfitidea点击:

Are negative array indexes allowed in C?

carrays

提问by bodacydo

I was just reading some code and found that the person was using arr[-2]to access the 2nd element before the arr, like so:

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

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

Is that allowed?

允许吗?

I know that arr[x]is the same as *(arr + x). So arr[-2]is *(arr - 2), which seems OK. What do you think?

我知道这arr[x]*(arr + x). 那么arr[-2]*(arr - 2),这似乎确定。你怎么认为?

回答by Matthew Flaschen

That is correct. From C99 §6.5.2.1/2:

那是正确的。来自 C99 §6.5.2.1/2:

The de?nition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))).

下标运算符[]的定义是E1[E2]等同于(*((E1)+(E2)))。

There's no magic. It's a 1-1 equivalence. As always when dereferencing a pointer (*), you need to be sure it's pointing to a valid address.

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

回答by James McNellis

This is only valid if arris a pointer that points to the second element in an array or a later element. Otherwise, it is not valid, because you would be accessing memory outside the bounds of the array. So, for example, this would be wrong:

仅当arr是指向数组中的第二个元素或后面的元素的指针时才有效。否则,它是无效的,因为您将访问数组边界之外的内存。因此,例如,这将是错误的:

int arr[10];

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

But this would be okay:

但这没关系:

int arr[10];
int* p = &arr[2];

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

It is, however, unusual to use a negative subscript.

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

回答by Matt Joiner

Sounds fine to me. It would be a rare case that you would legitimately need it however.

对我来说听起来不错。但是,您合法地需要它是一种罕见的情况。

回答by Igor Zevaka

What probably was that arrwas pointing to the middle of the array, hence making arr[-2]pointing to something in the original array without going out of bounds.

那可能是arr指向数组的中间,因此arr[-2]指向原始数组中的某些内容而不会越界。

回答by Paul R

I'm not sure how reliable this is, but I just read the following caveat about negative array indices on 64-bit systems (LP64 presumably): http://www.devx.com/tips/Tip/41349

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

The author seems to be saying that 32 bit int array indices with 64 bit addressing can result in bad address calculations unless the array index is explicitly promoted to 64 bits (e.g. via a ptrdiff_t cast). I have actually seen a bug of his nature with the PowerPC version of gcc 4.1.0, but I don't know if it's a compiler bug (i.e. should work according to C99 standard) or correct behaviour (i.e. index needs a cast to 64 bits for correct behaviour) ?

作者似乎在说 64 位寻址的 32 位 int 数组索引会导致错误的地址计算,除非数组索引显式提升为 64 位(例如,通过 ptrdiff_t 转换)。我实际上已经在 gcc 4.1.0 的 PowerPC 版本中看到了他的本质错误,但我不知道这是编译器错误(即应该根据 C99 标准工作)还是正确的行为(即索引需要强制转换为 64正确行为的位)?

回答by Ajinkya Patil

I know the question is answered, but I couldn't resist sharing this explanation.

我知道问题已得到解答,但我忍不住要分享这个解释。

I remember Principles of Compiler design, Let's assume a is an int array and size of int is 2, & Base address for a is 1000.

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

How a[5]will work ->

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

This explanation is also the reason why negative indexes in arrays work in C.

这种解释也是数组中的负索引在 C 中起作用的原因。

i.e. if I access a[-5]it will give me

即如果我访问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

It will return me object at location 990. By this logic we can access negative indexes in Array in C.

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

回答by Santiago Egido Arteaga

About why would someone want to use negative indexes, I have used them in two contexts:

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

  1. Having a table of combinatorial numbers that tells you comb[1][-1] = 0; you can always check indexes before accessing the table, but this way the code looks cleaner and executes faster.

  2. Putting a centinel at the beginning of a table. For instance, you want to use something like

     while (x < a[i]) i--;
    
  1. 有一个组合数表告诉你 comb[1][-1] = 0; 你总是可以在访问表之前检查索引,但这样代码看起来更干净并且执行得更快。

  2. 在桌子的开头放一个中心。例如,您想使用类似

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

but then you should also check that iis positive.
Solution: make it so that a[-1]is -DBLE_MAX, so that x&lt;a[-1]will always be false.

但是你也应该检查它i是积极的。
解决方案:让这个a[-1]-DBLE_MAX,这样x&lt;a[-1]将永远是假的。

回答by Rathinavelu Muthaliar

#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]);
}