Let's consider str has address 100 (Very simplified example).
It has 5 chars in it, so the addressed are 100, 101, 102, 103, 104, where in the 104 is '\0'
When you try to access str[i], it actually calculates the address str + i, and gets the value: *(str + i). And when you try to write the reversed way i[str], it also calculates the address i + str. So you get correct result.
Note that here is working pointer arithmetic (so for every type T you get the address pointer + sizeof(T))
And your
for(int i=0;str[i]!='\0';i++)
{
cout<<i[str]<<" ";
}
Will access addresses 100, 101, 102, 103, 104. And print the right values.