Логические различия в C и Java

Скомпилируйте и выполните этот код в C

#include <stdio.h>

int main()
{
  int a[] = {10, 20, 30, 40, 50};
  int index = 2;
  int i;

  a[index++] = index = index + 2;
  for(i = 0; i <= 4; i++)
    printf("%d\n", a[i]);
}

Вывод: 10 20 4 40 50

Теперь для той же логики в Java

class Check
{

  public static void main(String[] ar)
  {
    int a[] = {10, 20, 30, 40, 50};
    int index = 2;

    a[index++] = index = index + 2;
    for(int i = 0; i <= 4; i++)
      System.out.println(a[i]);
  }
}

Вывод: 10 20 5 40 50

Почему там выходное различие в обоих языках, вывод понятен для Java но я не могу понять вывод в C

Еще одна вещь, если мы применяем префикс ++ оператор, мы получаем тот же результат на обоих языках, почему?

35
задан 24 revs, 9 users 40% 10 April 2010 в 18:21
поделиться

1 ответ

Это потому, что a[index++] = индекс = индекс + 2; вызывает Неопределенное поведение в C. Взгляните на this

From the link:

...во втором предложении сказано: если объект записывается в пределах полного выражения, то любой и все обращения к нему в пределах одного и того же выражения должны быть непосредственно вовлечены в вычисление записываемого значения. Это правило фактически ограничивает юридические выражения теми, в которых доступ к ним явно предшествует модификации. Например, разрешен старый режим ожидания i = i + 1, поскольку доступ i используется для определения конечного значения i. Пример

 a[i] = i++

запрещено, так как один из обращений к i (, который находится в a[i]) не имеет никакого отношения к значению, которое в итоге хранится в i (что происходит в i++), и поэтому нет хорошего способа определить - ни для нашего понимания, ни для компилятора - должен ли этот доступ иметь место до или после хранения инкрементированного значения. Так как нет хорошего способа определить его, Стандарт заявляет, что он неопределен и что переносимые программы просто не должны использовать такие конструкции. Аналогично a[i++]=i (который вызывает UB) ваше выражение тоже вызывает UB.

Ваше выражение также имеет аналогичное поведение.

Поведение хорошо определено в Java.

64
ответ дан 27 November 2019 в 07:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: