The standard C++ says that one of the operands of [] operator has to be a pointer and the other has to be an integer.
Since i is an integer and &j is a pointer it would compile fine.
Doing that may cause segmentation fault or unexpected results at runtime but is syntactically correct
pointer_to_something [ index_value] is the same as index_value [pointer_to_something]
In this case because the values are on the stack, the two integers are next to each other - in this case i is higher in memory than j.
So i is next along in memory from j - so &j[1] is i (butnot the other way around|)
EDIT:
Special Note:
I believe the order in which local variables are stored on the stack is compiler dependent