awesome-everything EN
↑ Обратно к восхождению

Базовый CS с нуля

Control flow: трассировка кода

Суть Прочитайте четыре маленькие программы и протрассируйте их вручную: предскажите число итераций loop и вывод, найдите off-by-one на границе и разберите short-circuit как цепочку conditional jump.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на middle-высоте — в небе
◷ 14 min

Единственный надёжный способ узнать, что делает branch или loop, — протрассировать его так, как это делает CPU: следить за program counter и переменными, по одному шагу. Прочитайте каждый сниппет, предскажите результат вручную, затем проверьте себя.

Цель

Отработайте главный навык unit: проходить conditional и loop вручную, точно считать итерации, находить off-by-one, переворачивающий границу, и рассуждать о short-circuit как о цепочке conditional jump, в которую он компилируется.

Сниппет 1 — посчитайте итерации

let count = 0;
let i = 1;
while (i <= 5) {   // обратите внимание: <= , не <
  count++;
  i++;
}
// чему равно count?
Викторина

Каково итоговое значение count?

Сниппет 2 — граница off-by-one

const a = [10, 20, 30];   // длина 3, валидные индексы 0,1,2
let i = 0;
while (i <= a.length) {   // <= length, не < length
  console.log(a[i]);
  i++;
}
Викторина

Сколько раз исполняется тело loop и в чём баг?

Сниппет 3 — short-circuit как цепочка jump

function check(user) {
  // && останавливается на первом ложном операнде
  if (user && user.active && user.age >= 18) {
    return "allowed";
  }
  return "denied";
}
check(null);   // user равен null
Викторина

check(null) возвращает 'denied'. Почему user.active никогда не вычисляется, в терминах машинного уровня?

Сниппет 4 — вложенный loop и conditional

let sum = 0;
for (let i = 0; i < 3; i++) {     // внешний: i = 0,1,2
  for (let j = 0; j < 3; j++) {   // внутренний: j = 0,1,2
    if (i === j) {                // только диагональ
      sum += 1;
    }
  }
}
// чему равно sum?
Викторина

Каково итоговое значение sum?

Итог

Трассировка вручную — это весь навык. Число итераций loop — ровно столько, сколько раз его проверка остаётся истинной, а оператор границы (&lt; против &lt;=) — то место, где живут баги off-by-one: здесь чтение на один элемент за концом массива из 3 элементов. Short-circuit && компилируется в цепочку conditional jump, уходящих на ложный путь в момент, когда операнд становится ложным, — поэтому последующие операнды даже не читаются (и поэтому проверка на null защищает чтения после неё). Вложенные loop перемножают число итераций, но защищающий if всё равно срабатывает только при своём условии. Если сомневаетесь — проводите program counter и переменные по одному шагу.

Продолжить восхождение ↑Control flow: постройте jump-машину
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.