В чем разница между индексом приращения в скобках и вне скобок в Java? - PullRequest
0 голосов
/ 23 октября 2018

Я делаю несколько упражнений и наткнулся на что-то, о чем я мало что знаю.Ниже приведен код и часть, которую я не полностью понимаю, я вставлю между звездочками, например *this*.

public int[] seriesUp(int n) {
  int[] result = new int[n * (n + 1) / 2];
  int i = 0;
  for (int j = 1; j <= n; ++j)
    for (int k = 1; k <= j; ++k)
      result[*i++*] = k;
  return result;
}

Может кто-нибудь объяснить, в чем разница между выше и ниже?

public int[] seriesUp(int n) {
  int[] result = new int[n * (n + 1) / 2];
  int i = 0;
  for (int j = 1; j <= n; ++j)
    for (int k = 1; k <= j; ++k)
      result[i] = k;
      *i++;*
  return result;
}

Я изменил i++ в скобках индекса на i и увеличил i ниже, но это дает совершенно другой вывод, хотя на мой взгляд это то же самое.

1 Ответ

0 голосов
/ 23 октября 2018

TL; DR

Этот

for (int j = 1; j <= n; ++j)
  for (int k = 1; k <= j; ++k)
    result[i++] = k;

эквивалентен приведенному ниже коду (отформатирован в фигурных скобках), который увеличивается i внутри два цикла for:

for (int j = 1; j <= n; ++j) {
  for (int k = 1; k <= j; ++k) {
    result[i++] = k;
  }
}

И этот

for (int j = 1; j <= n; ++j)
  for (int k = 1; k <= j; ++k)
    result[i] = k;
    i++;

эквивалентен этому коду (отформатирован в фигурных скобках), который приращения i после выполняются два цикла for:

for (int j = 1; j <= n; ++j) {
  for (int k = 1; k <= j; ++k) {
    result[i] = k;
  }
}
i++;

В основном, когда фигурные скобки не используются, такие инструкции, как for, while, if и т. Д. Интерпретировать только следующую строку как блок кода, который будет выполнен как часть его оператора.

В вашем случае вы заменили result[i++] = k; (одна строка) на(две строки)

result[i] = k;
i++

оставляя, таким образом, вторую строку (i++) из оператора, который будет выполнен для for.Следуя тому же принципу, внешний цикл также игнорирует предложение i++.

При правильном использовании фигурных скобок и форматировании кода это никогда не должно происходить.


Long Story

Это оператор for:

for ( [ForInit] ; [Expression] ; [ForUpdate] ) Statement

Где Statement может быть (среди прочих) ExpressionStatement или Block.

ExpressionStatement, который вы использовали, делая result[i++] = k;, было Assignment (два из них, на самом деле: result[i] = k; и i = i + 1, но в одной строке), которая равна:

LeftHandSide AssignmentOperator Expression
result[i]    =                  k         ; // leaving out the `++` operation for simplicity here

Теперь, когда вы перешли ко второму варианту без использования фигурных скобок, Statement используется for по-прежнему является первой строкой рядом с ней

result[i] = k; // <-- this keeps being the `Statement` taken by the `for`
i++            // and this line is not considered as a statement to be used by the for anymore

Но, если бы вы использовали фигурные скобки, это стало бы оператором Block в форме

{ [BlockStatements] }

Где BlockStatements равно

BlockStatement {BlockStatement}

И каждый BlockStatement может быть (среди прочих) Statement.Таким образом, вы могли бы поставить столько Assignment с (помните, что это Statement), сколько вы хотите, чтобы их выполняли операторы for.


Далеепоказания :

...