Hacker News new | ask | show | jobs
by ThatOtherPerson 4515 days ago
Can you explain your array[i] / i[array] reference? I can't find it on Google.
5 comments

  By definition, the subscript operator [] is interpreted in such a
  way that ‘‘E1[E2]’’ is identical to ‘‘*((E1) + (E2))’’.  Because
  of the conversion rules which apply to +, if E1 is an array and
  E2 an integer, then E1[E2] refers to the E2th member of E1.
  Therefore, despite its asymmetric appearance, subscripting is a
  commutative operation.¹
¹ Dennis M Ritchie, C Reference Manual, 1975 http://cm.bell-labs.com/cm/cs/who/dmr/cman.pdf (A revised version of this became Appendix A to K&R.)
There's an answer [1] on the linked SO thread (flip to the first page) but basically, the following two lines are equivalent in C:

a[10] 10[a]

This is because a[10] is equivalent to (a + 10), and 10[a] is equivalent to (10 + a), as the first comment on this answer explains.

[1] http://stackoverflow.com/questions/1995113/strangest-languag...

From the c standard[0]:

> The definition of the subscript operator [] is that E1[E2] is identical to (* ((E1)+(E2))).

Since * (E1 + E2) is commutative, E1[E2] == E2[E1].

[0] http://c0x.coding-guidelines.com/6.5.2.1.html

Now obviously, c arrays are just strips of memory allocated to that array, so you can access them using the address of the start of the address and the offset (number of array items to skip). To access them, you sum the address and the offset, then you have the address of the item.

     [~~~~~~~~~~~~~~~~[a~~~~~~~b~~]~~~] Memory
     ^–––––––––––––––––^                Address
                       ^–––––––^        Offset
And now, a[b] is just short hand for the pointer arithmetic going on and you could just use any two ints and access any arbitrary memory address (i assume the compiler enforces that this doesn't happen).

     address[offset] => *(address + offset) => getValueAtAddress(valueIn(address) + valueIn(offset))

    a[b]  => *(a + b) => getValueAtAddress(valueIn(a) + valueIn(b))
    b[a]  => *(b + a) => getValueAtAddress(valueIn(a) + valueIn(b))
Those two are obviously the same so *(a + b) == b[a] == a[b]
I think the trick is that array[i] and i[array] will always be the same value in C.

It's confusing because array[i] makes sense but i[array] doesn't (how the hell can you use an array as an index on an integer?)

It works because array is a pointer to a memory address and i (or index) is an offset. array[i] will add the index to the memory address and return the value there, where as i[array] will add the memory address to the index. Since array+index == index+array, they point to the same memory and return the same value.