0

I am not able to make sense of the first line inside the loop body.

How to interpret this statement: printf("%d", i++[a]);

    #include <stdio.h>

    int main()
    {

        int a[5] = {1,2,3,4,5};

        for(int i=0; i<5; i+2){
            printf("%d", i++[a]);
            printf(",%d",i);
        }

        return 0;
    }

Output

1,12,23,34,45,5

EsmaeelE
  • 2,331
  • 6
  • 22
  • 31
ishon19
  • 327
  • 4
  • 14

4 Answers4

3

This

i++[a];

where a is an array is valid as a[i] and i[a] are same. In this particular case post increment ++ happens later i.e first i[a] executes and then i increments.

From the C Standard

6.5.2.1 Array subscripting

A postfix expression followed by an expression in square brackets [] is a sub scripted 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).

Achal
  • 11,821
  • 2
  • 15
  • 37
2

The first line

printf("%d", i++[a]);

prints the ith element of the a array and then subsequently increments i.

Remember, that a[42] and 42[a] is the exact same thing in C++ (since "address + offset" is the same as "offset + address" under the hood).

This is the same thing written in a more conventional manner:

printf("%d", a[i++]);
Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
  • Note: the increment of `i` can happen before or after the array element is accessed. In C (before C18, I don't know if the rules changed with the latest revision), there is no requirement for the order of operations in `i++[a]`. – pmg Aug 03 '19 at 13:21
  • @pmg I believe you are not correct. `i++` will use the current value of `i` before incrementing. `++i` would increment first and *then* use the value of `i`. I'm *fairly sure* this is well defined in the context of array indexing. And the answer by @Achal provides chapter and verse from the (C) standard (but this is (AFAIK) the same for C++). – Jesper Juhl Aug 03 '19 at 13:23
  • Assuming `i == 0`, `i++[a]` ... will (possibly only pre-C18) do either one of a) `i=1;a[0];` or b) `a[0];i=1;` – pmg Aug 03 '19 at 13:25
  • @pmg I still disagree. Please point to the part of the C++ standard that supports your argument. I don't believe you can find one. – Jesper Juhl Aug 03 '19 at 13:31
  • @JesperJuhl: [C11 sequence points (Annex C)](http://port70.net/~nsz/c/c11/n1570.html#C) – pmg Aug 03 '19 at 13:36
  • @JesperJuhl: [C11 6.5p3](http://port70.net/~nsz/c/c11/n1570.html#6.5p3) "... Except as specified later, side effects and value computations of subexpressions are unsequenced." – pmg Aug 03 '19 at 13:39
  • @pmg if that reading applied to array indexing (which I believe it does not), then `a[i++]` would also be unsequenced, which I hope we can agree is not the case. And since `i++[a]` is quite literally *the exact same thing* as `a[i++]`, then it is also not unsequenced. – Jesper Juhl Aug 03 '19 at 13:43
  • The compiler could conceivably even emit code that fetches the `a` element and increments the `i` variable at the same time, in parallel: hence **unsequenced** :) – pmg Aug 03 '19 at 13:45
  • @pmg then you should also downvote https://stackoverflow.com/a/16869073/5910058 - also, this language seems to contradict you "A postfix expression followed by an expression in square brackets [] is a sub scripted 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)." – Jesper Juhl Aug 03 '19 at 13:58
  • @JesperJuhl: your answer got my upvote, not downvote (and the answer you linked to here is wrong and got a downvote -- not that I'm on a crusade for the proper explanation of order of evaluation or anything). – pmg Aug 03 '19 at 14:08
  • @JesperJuhl: The *side effect* of incrementing `i` is unsequenced with respect to indexing into `a`. `i++` will *evaluate* to the current value of `i`, and `++i` will evaluate to the current value of `i + 1`, but `i` won’t necessarily be updated immediately after evaluation; it’s only guaranteed to be updated by the next sequence point. – John Bode Aug 03 '19 at 15:55
  • @JohnBode But as far as indexing into the array and accessing a value is concerned, we argree that everything is well defined? Right? Btw; I don't think sequence points are a thing in the most recent versions of the standard.. they are of course still there in some sense, but the language has changed. – Jesper Juhl Aug 03 '19 at 15:58
  • @JesperJuhl: Yeah, as long as we’re not doing something like `a[i++] = i` or `a[i] = ++i`, everything’s good. `a[i++]` has the same result as `a[i]` and `a[++i]` has the same result as `a[i+1]` - it’s just that the update to `i` may happen before or after the array access. – John Bode Aug 03 '19 at 16:04
  • @JohnBode Of course. But that's not what this question (or answer) is about. – Jesper Juhl Aug 03 '19 at 16:07
1

The loop section can be re-written in this form as they are exactly same.

We know that a[1] and 1[a] are same things, second member of array.

for(int i=0; i<5; i+2){
    printf("%d", a[++i]);
    printf(",%d",i);
}

The printf("%d", a[++i]); in turn can be interpret as

printf("%d", a[i]);
i++;

As a side note, i+2 in third section of for loop is useless and can be removed.

for(int i=0; i<5;){
    printf("%d", a[++i]);
    printf(",%d",i);
}
EsmaeelE
  • 2,331
  • 6
  • 22
  • 31
0
printf("%d", i++[a]);

a[i] and i[a] are the same.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76