1

Array declaration:

int arr [ ]={34, 65, 23, 75, 76, 33}; 

Four notations: (consider i=0)

arr[i]

and

*(arr+i)

and

*(i+arr)

and

i[arr]
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
daya
  • 160
  • 2
  • 14
  • 4
    Just use the first one. Forget the others. – Martin James Jul 11 '17 at 16:13
  • 5
    `x[y]` is the same as `*(x+y)` *by definition*. The others just follow from the commutative property of the integer `+` operation in C. – DaoWen Jul 11 '17 at 16:14
  • Awfully close, if not a duplicate: https://stackoverflow.com/q/381542/10077 – Fred Larson Jul 11 '17 at 16:18
  • 1
    Please clarify your question. As others have indicated, it's this way by design, so what sort of answer are you looking for when you ask "why is it this way?" Are you asking "Why was the language designed this way instead of that way?" Or are you asking something else entirely? – Brian Cain Jul 11 '17 at 16:18
  • @Brian I am not asking why language's syntax is so. I read that there are 4 ways to implement a same task but unable to understand the fourth notation. – daya Jul 11 '17 at 16:28

6 Answers6

6

Lets take a look at how your array is laid out in memory:

low address                   high address
|                             |
v                             v
+----+----+----+----+----+----+
| 34 | 65 | 23 | 75 | 76 | 33 |
+----+----+----+----+----+----+
^    ^    ^    ^
|    |    |    ...etc
|    |    |
|    |    arr[2]
|    |
|    arr[1]
|
arr[0]

That the first elements is arr[0], the second arr[1] is pretty clear, that's what everybody learns. What is less clear is that the compiler actually translates an expression such as arr[i] to *(arr + i).

What *(arr + i) does is first get a pointer to the first element, then do pointer arithmetic to get a pointer to the wanted element at index i, and then dereference the pointer to get its value.

Due to the commutative property of addition, the expression *(arr + i) is equal to *(i + arr) which due to the above mentioned translation is equal to i[arr].


The equivalence of arr[i] and *(arr + i) is also what's behind the decay of an array to a pointer to its first element.

The pointer to the arrays first element would be &arr[0]. Now we know that arr[0] should be equal to *(arr + 0) which means &arr[0] has to be equal to &*(arr + 0). Adding zero to anything is a no-op, so leading to the expression &*(arr). Parentheses with only one term and no operator can also be removed, leaving &*arr. And lastly the address-of and dereference operator are each other opposites and cancel out each other, leaving us with simply arr. So &arr[0] is equal to arr.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
3

Each element in the array, have a position in memory. The positions in the arrays are sequential. The arrays in C are pointers and always point the first direction on memory for the collection (first element of the array).

arr[i] => Gets value of "i-position" in the array. It is the same that arr[i] = *(arr + i)

*(arr+i) => Gets value that is in memory by adding the position in memory that point arr and i value.

*(i+arr) => Is the same that *(arr+i). The sum is commutative.

i[arr] => Is the same that *(i+arr). It's another way of representing.

VIX
  • 605
  • 4
  • 15
1

They are the same because the C language specification says so. Read n1570

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
1

The notation a[i] is syntactic sugar for *(a+i).

The first one is mathematical syntax (symbolics closer of what human brain is educated with) while the second one corresponds directly to one assembler instruction.

On the other hand *(a+i)=*(i+a)=i[a] because the arithmetic of pointers is commutative.

alinsoar
  • 15,386
  • 4
  • 57
  • 74
0

It works because an array variable in C (i.e. arr in your example) is just a pointer to the beginning of an array of memory locations. A pointer is number which represents the address of a specific memory location. When you put and '*' in front of a pointer, it means "give me the data in that memory location".

  • So, if arr is a pointer to the beginning of the array, *(arr) or *(arr + 0) is the data in the 0th index of the array, and *(arr + 1) is the data in the 1st index, and so on.
  • An expression which looks like A[B] essentially gets translated into something like *(A+B). So, arr[0] = *(arr + 0) and arr[i] = *(arr+i), etc.
  • And because A+B = B+A, the two are interchangeable. Meaning *(arr+i) = *(i+arr).
  • And because arr[i] = *(arr+i) and *(arr+i) = *(i+arr), it should make sense that arr[i] = i[arr].
Sanjeev
  • 1,517
  • 1
  • 18
  • 30
0

These are the same because of how the array subscript operator [] is defined.

From sectino 6.5.2.1 of the C standard:

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).

The expression arr[i] in your example is of the form E1[E2]. Because the standard states that this is the same as *(E1+E2) that means that arr[i] is the same as *(arr + i).

Because of the commutative property of addition, *(arr + i) is the same as *(i + arr). Applying the equivalence rule above to this expression gives i[arr].

So in short, those 4 expressions are equivalent because of how the standard defines array subscripting and because of the commutative property of addition.

dbush
  • 205,898
  • 23
  • 218
  • 273