Ответ 1
Это потому, что a[index++] = index = index + 2;
вызывает Undefined Поведение в C.
Посмотрите this
Из ссылки:
.. во втором предложении говорится: если объект написан в полном выражении, любой доступ к нему в пределах одного и того же выражения должен быть непосредственно задействован в вычислении значения, которое должно быть записано. Это правило эффективно ограничивает юридические выражения теми, в которых доступ явно предшествует модификации. Например, старый резерв я = я + 1 разрешен, поскольку доступ я используется для определения конечного значения i. Пример
a[i] = i++
запрещен, потому что один из доступа я ( тот, что в [i]) не имеет ничего общего со значением, которое заканчивается тем, что оно хранится в я (что происходит в я ++), и поэтому нет хороший способ определить - как для нашего понимания, так и для компилятора - должен ли доступ иметь место до или после того, как инкрементное значение сохраняется. Поскольку нет хорошего способа определить его, стандарт объявляет, что это undefined, и что переносные программы просто не должны использовать такие конструкции. Подобно
a[i++]=i
(который вызывает UB), ваше выражение также вызывает UB.
Ваше выражение также имеет аналогичное поведение.
Поведение хорошо определено в Java
.