Они не эквивалентны, потому что постфиксные операторы имеют более высокий приоритет, чем унарные.Это означает, что *fib_sequence[i]
на самом деле означает *(fib_sequence[i])
.Тогда под эквивалентностью *(E)
и (E)[0]
, которую вы правильно понимаете, это выражение означает (fib_sequence[i])[0]
, из которого мы можем отбросить ненужные скобки, чтобы получить fib_sequence[i][0]
.
Запомните постфикс в сравнении с унарным / префиксом: *E
, ++E
, &E
и другие являются унарными операторами.E(...)
, E[]
, E->memb
, E.memb
- это постфиксы.
Все унарные и постфиксы можно объединять в одно целое.Когда postfix комбинируется с postfix, становится ясно: они идут в одном направлении, от корневого выражения слева направо: E[i]->foo.memb(arg)[blah]
.Приоритет все тот же, и ассоциативность, очевидно, может быть только слева направо.
Когда унарные объединены, то же самое в противоположном направлении: sizeof (T) &*++E
.Приоритет все тот же, а ассоциативность справа налево.Все они выше, чем различные бинарные операторы.
Если мы соединим эти два, нам вряд ли придется думать:
sizeof (T) &*++E[i]->foo.memb(arg)[blah]
Как только мы просканируем унарные операторы, чтобы найти E
, ситуация с приоритетом будет просто такой:
sizeof (T) &*++ ( E[i]->foo.memb(arg)[blah] )
^---------------------------^
все постфиксовые крафт имеют более высокий приоритет, чем унарный.
Постфиксы имеют наивысший приоритет, за ними следуют унарные символы, затем все остальное.