Правила трассировки: 1–32
Все правила таблиц трассировки за курс — одним списком, как их вводили дни. Номера сквозные: на них ссылаются подсказки и сообщения проверки. Читать подряд не нужно — держите страницу открытой рядом с table.txt. Новых правил контрольная не вводит: таблица в kt6 сверяется по этому списку.
Формат таблицы
# шаг | строка | boxes | len(boxes) | cap(boxes) | first | len(first) | cap(first)
1 | 8 | [] | 0 | 4 | - | - | -
2 | 9 | ? | ? | ? | ? | ? | ?- файл
table.txt; первая строка — шапка-комментарий с#, колонка на переменную; - шаг и номер строки заполнены заранее, меняются только
?; - пробелы вокруг
|и регистр не важны; прочерк можно набрать любым тире —-,—,–; - строки, начинающиеся с
#, не проверяются.
Строки и значения — день 02
- Одна строка таблицы — одна выполненная строка кода внутри
main, включая строки с печатью. С дня 11 — строка на каждую выполненную строку кода и внутри вызванных функций (правила 16–18). - Значения записываются после выполнения шага.
- Переменной ещё нет — прочерк
-. Это не ноль. - То, что шаг не трогал, переписывается из строки выше: пустых клеток не бывает.
- Правая часть считается по предыдущей строке таблицы.
- Номера строк — по исходному файлу программы, без ваших вставок с отладочной печатью.
Ветвления — день 06
- Строка с
ifили} else if— шаг; значения в ней те же, что строкой выше: условие только читает. - Строки
} else {и одинокая}— не шаги. - Строки невыполненных веток в таблицу не попадают: номера идут с пропусками.
- После первой сработавшей ветки остальная цепочка — не шаги.
Циклы — день 08
- Строка
for— шаг каждый раз, когда программа к ней приходит. В первый раз выполняются начальное значение и проверка, в следующие — третья часть (i++) и проверка; в таблицу идут значения после всего этого. - Последний шаг со строкой
for— тот, где условие ложно; он есть всегда, и переменная цикла на нём уже «за границей». - После цикла переменной цикла нет — прочерк.
- Строки
breakиcontinue— шаги. Значения в них переписываются из строки выше. Послеcontinueследующий шаг — строкаfor, послеbreak— первая строка после цикла. - Шаги нумеруются подряд, номера строк повторяются. Самопроверка: строка
forвстречается на один раз больше, чем выполнилось тело.
Вызов функции — день 11
- Колонка «где мы» — имя функции, чью строку сейчас выполняем:
main,boxes. - Строка с вызовом — шаг, и она встречается в таблице дважды: уход в функцию (результата ещё нет) и возврат (присваивание доделано).
- Первый шаг внутри функции — строка её заголовка: на нём параметры получают копии аргументов. Самое забываемое правило.
- Строка
return— шаг; значения на нём те же, что строкой выше. - Переменные другой функции — прочерк; переменные
main, пока мы внутри функции, показываются как есть и не меняются.
Одноимённые переменные и сокращённый вызов — день 12
- Одноимённые переменные — разные колонки:
tripsиtrips в if. До объявления внутренней и после закрывающей}её блока — прочерк. - Строка с вызовом функции — один шаг, если шаги внутри функции не расписываются: в таблицу идут значения вызвавшего, уже с присвоенным результатом.
Несколько функций — день 13
- Одноимённые переменные разных функций — разные колонки, и в заголовке написано, чья:
total (main),total (loadPlan). - Вложенный вызов раскрывают отдельной таблицей, а в первую подставляют её результат.
Самопроверки для функций: строк с именем функции столько, сколько строк её тела выполнилось, плюс одна на заголовок; строка вызова встречается парами — уход и возврат (правило 17), кроме случая правила 22.
Срез в клетке и цикл range — день 16
- Срез в клетке таблицы пишется так, как его печатает
fmt.Println: элементы через пробел в квадратных скобках —[12 40 5]. Пустой срез —[], а не прочерк: срез уже есть, элементов в нём нет. Изменился один элемент или добавился новый — в клетку идёт весь срез целиком, уже с изменением. - Строка
for i, v := range s— шаг в начале каждого прохода: на нёмiуже получила индекс, аv— копию элемента. После последнего прохода программа ещё раз приходит на эту строку и узнаёт, что элементов больше нет, — это тоже шаг, и на нёмiиvуже прочерк.
Правила 11–13 дня 08 для range: у него нет значения «за границей», поэтому на последнем шаге сразу прочерк.
len, cap и общий массив — день 17
- У каждого среза в таблице три колонки: сам срез,
lenиcap. В клетку среза по правилу 25 идут элементы с нулевого поlen - 1; ячейки за длиной не пишутся. У подсрезаs[a:b]длинаb - a, ёмкостьcap(s) - a. - Срезы, взятые один из другого, делят массив. Запись через любой из них на том же шаге меняет все срезы, чьё окно видит эту ячейку;
lenиcapот записи не меняются. appendприlenменьшеcapпишет в тот же массив, приlen, равномcap, — в новый. В первом случае элемент на том же шаге появляется во всех срезах, чьё окно видит ячейку, аcapпрежний. Во втором срез с этого шага ни с кем ячеек не делит, а новыйcapне вычисляют: он вписан в заготовку или взят из вывода.
Самопроверка: если клетка среза изменилась на шаге, где его имени в строке кода нет, в строке должен стоять его сосед по массиву — правило 28 или 29.
Колонка map — день 18
- Колонка map записывается так, как её печатает
fmt.Println:map[ключ:значение ключ:значение]— пары через пробел, ключ и значение через двоеточие, ключи по возрастанию, строки без кавычек. Пустая map —map[]; map, которая ещё не объявлена, — прочерк-. Порядок в клетке — порядок ключей, а не порядок записи. - Новый ключ появляется в колонке только при записи:
m[k] = …,m[k]++,m[k] += …— даже если прибавили ноль. Чтениеx := m[k]иx, ok := m[k]колонку map не меняет, даже когда ключа нет.delete(m, k)убирает пару;deleteключа, которого нет, ничего не меняет. - Map, переданная в функцию, — та же самая map: запись внутри функции меняет колонку map вызывающего. Если вызов — один шаг (правило 22), изменение видно уже в строке вызова. Если шаги функции расписаны, колонка вызывающего меняется в той строке функции, где сделана запись. Это исключение из правила 20: у переменных
intиstringвызывающего так не бывает.
Обход for k, v := range m по самой map по шагам не расписывают: порядок меняется от запуска к запуску. Обход slices.Sorted(maps.Keys(m)) — обычный обход среза, для него действуют правила дня 16.
День 19 новых правил не вводил: список заканчивается на 32.
Как свериться с таблицей
Отладочная печать — в копии программы в scratch, не в файле задания (правило 6). После каждой строки — все колонки таблицы:
fmt.Println(boxes, len(boxes), cap(boxes), first, len(first), cap(first))До объявления переменной её в печать не включают — в таблице у неё прочерк. Последняя строка таблицы обязана совпасть с тем, что печатает сама программа.
На контрольной точке так не делают: таблица заполняется до запуска, по картинке памяти, а запуск нужен только для сверки последней строки.
Дальше: правила контрольной точки 4 и задачи — course next