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:
|a|b|c|
Sounds fine to me. It would be a rare case that you would legitimately need it however.
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
, and the base address for a
is 1000
.
How will a[5]
work ->
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; i.e., if I access a[-5]
it will give me:
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 the object at location 990. So, by this logic, we can access negative indexes in arrays in C.
That is correct. From C99 §6.5.2.1/2:
The definition of the subscript operator [] is that E1[E2] is identical to (*((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.
#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]);
}
About why would someone want to use negative indexes, I have used them in two contexts:
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.
Putting a centinel at the beginning of a table. For instance, you want to use something like
while (x < a[i]) i--;
but then you should also check that i
is positive.
Solution: make it so that a[-1]
is -DBLE_MAX
, so that x<a[-1]
will always be false.
What probably was that arr
was pointing to the middle of the array, hence making arr[-2]
pointing to something in the original array without going out of bounds.