1

I haven't come across a similar notation in any other programming language, i.e., I am used to seeing the subscript within the brackets (and not the other way round). I understand how given an array foo, foo essentially is a pointer to the base address of the array; and how pointer notations correlate to array notations, i.e. I get the rationale behind why foo[i], *(foo + i), *(i + foo) are all equivalent... But I don't understand the rationale behind how i[foo] is also equivalent to the three mentioned above, or how it works. Maybe rephrasing this notation in English will help, but I don't see how to do that.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
computronium
  • 445
  • 2
  • 11
  • 1
    Ask yourself, "what possible alternative meaning could `7[arrayname]` have?" K&R, decided it makes no difference so might as well make it communitive. – wallyk Oct 13 '20 at 15:52
  • 2
    See http://c-faq.com/aryptr/joke.html – Shawn Oct 13 '20 at 15:52
  • 2
    I think it was explained in the K&R book - a[b] was just a _syntax sugar_ for *(a+b) which obviously is commutative. – fukanchik Oct 13 '20 at 15:53
  • @wallyk so it's totally arbitrary? – computronium Oct 13 '20 at 15:53
  • 2
    Please see [Accessing arrays by index array in C and C++](https://stackoverflow.com/questions/5073350/accessing-arrays-by-indexarray-in-c-and-c) – Weather Vane Oct 13 '20 at 15:53
  • 1
    @computronium not arbitrary, it is explained in the resources. `a[i]` is `*(a+i)` is `*(i+a)` is `i[a]`. – Weather Vane Oct 13 '20 at 15:56
  • 1
    @computronium:: *Arbitrary* seems heavy handed. However, allowing either expression inside the square brackets feels more like relaxation of the syntax to permit flexibility when it might not be clear what the types of parameters would be, for example in a preprocessor situation. – wallyk Oct 13 '20 at 15:57
  • @wallyk it makes perfect sense when I think of `foo[i] == *(foo +i ) == *(i + foo) == i[foo]` thanks! – computronium Oct 13 '20 at 15:58
  • ...`+` is obviously commutative and thus `foo[i]` and `i[foo]` should mean the same thing. – computronium Oct 13 '20 at 16:04

1 Answers1

2

According to the C Standard (6.5.2.1 Array subscripting)

2 A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).

So due to the commutative nature of the operation + you can write

a[i]

as either

*( a + i )

or like

i[a]

Let's consider the following declaration of a multi-dimensional array

char * a[][2] =
{
    { { "Hello" }, { "World" } },
    { { "Hi" }, { "everybody" } }
};

To access the letter 'v' of the string literal "everybody" you can write en expression

a[1][1][1]    

that is calculated like

*( *( *( a + 1 ) + 1 ) + 1 )

The expression can be rewritten like

*( 1 + *( 1 + *( 1 + a ) ) )

that in turn can be rewritten like

1[1[1[a]]]

Here is a demonstrative program

#include <stdio.h>

int main( void )
{
    char *a[][2] =
    {
        { { "Hello" }, { "World" } },
        { { "Hi" }, { "everybody" } }
    };

    printf( "%c\t%c\n", a[1][1][1], *( *( *( a + 1 ) + 1 ) + 1 ) );
    printf( "%c\t%c\n", *( 1 + *( 1 + *( 1 + a ) ) ), 1[1[1[a]]] );

}

Its output is

v       v
v       v
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thanks a ton for illustrating how it all breaks down for multidimensional arrays. Couldn't have been explained better. – computronium Oct 13 '20 at 16:12