简体   繁体   中英

how will this cout statement run

int a[10][5];
for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        cout << i[j[a]];
        cout << j[i[a]];
    }
}  

Edit :assume the values are already initialized to the array and is this cout valid then?

please explain the i[j[a]]; part only regardless of the program I'm concerned about that statement only!

cout << i[j[a]];
cout << j[i[a]];

In C++, the X[Y] notation is lexically equivalent to *(X+Y) :

[C++11: 5.2.1/1]: [..] The expression E1[E2] is identical (by definition) to *((E1)+(E2)) [..]

That means that Y[X] is equivalent to *(Y+X) , which is the same as *(X+Y) since addition is commutative .

For some reason, the author has decided to try to be "clever" by writing this confusing code.

By commutativity and the definition for X[Y] alone:

i[j[a]] => i[*(j+a)] => *(i+*(j+a)) => *(*(a+j)+i) => *(a[j] + i) => a[j][i]
j[i[a]] => j[*(i+a)] => *(j+*(i+a)) => *(*(a+i)+j) => *(a[i] + j) => a[i][j]

Your cout statements are, then, equivalent to:

cout << a[j][i];
cout << a[i][j];

In any case, the loop attempts to read past the array bounds because there are only 5 integers in each element of the array a , whereas your inner loop attempts to go all the way up to 10 .

The practical result of this is undefined, so you could get silent success, silent failure, arbitrary values, a segmentation fault, a power cut, a black hole, a pony for Christmas, a toe amputation or a new bike.

Even when the loop condition is fixed, note that the first statement is semantically incorrect (assuming you continue to ascribe the first dimension to the outer loop and the second dimension to the inner loop).

C arrays have a strange quirk that allows them to be accessed through the "opposite" direction. This is deeply rooted in the pointer arithmetic of arrays. For example, a[1] is equivalent to *(a + 1) . Likewise, 1[a] is equivalent to *(1 + a) . Due to the commutative nature of addition, this works out quite nicely. More details can be found here .

With that knowledge in tact, the expression i[j[a]] can be broken down into two different parts. j[a] is equivalent to *(j + a) which would return another array due to the multi-dimensional nature of the array you have, for example purposes we'll call this returned array p . Then you have the statement i[p] which would be equivalent to *(i + p) . Bringing it back all together would show you that i[j[a]] is equivalent to *(i + *(j + a)) . Indeed, this means that i[j[a]] is just an obfuscated way of writing a[j][i] .

In C/C++, you can either subscript a pointer with an integral index, or subscript an integral index with a pointer, and the meaning (semantics) are exactly the same. I don't know offhand why the heck the insane syntax is valid, but so it is, and apparently so it will remain for ever after.

#include <stdio.h>

int main(int argc, char** argv)
{
  int i = 1, array[10];
  printf("%ld\n", &(i[array])-&(array[i]));
  return 0;
}

Output:

0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM