Are negative array indexes allowed in C?

后端 未结 8 2195
隐瞒了意图╮
隐瞒了意图╮ 2020-11-22 13:56

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|         


        
相关标签:
8条回答
  • 2020-11-22 14:33

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

    0 讨论(0)
  • 2020-11-22 14:34

    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.

    0 讨论(0)
  • 2020-11-22 14:47

    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.

    0 讨论(0)
  • 2020-11-22 14:47
    #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]);
    }
    
    0 讨论(0)
  • 2020-11-22 14:52

    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--;
      

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

    0 讨论(0)
  • 2020-11-22 14:54

    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.

    0 讨论(0)
提交回复
热议问题