
Как можно заставить счетчик сохранять значения между разными блоками, например, во вложенных циклах? Например
\newcommand\example
{%
\newcount\N
\loop
{\loop
\the\N\quad
\ifnum\N<5
\advance\N by 1
\repeat
}%
\the\N
\ifnum\N<5
\advance\N by 1
\repeat
}
вернется
0 1 2 3 4 5
0
1 2 3 4 5
1
2 3 4 5
2
3 4 5
3
4 5
4
5
5
Каким образом можно добиться сохранения значения \N
и, следовательно, такого результата?
0 1 2 3 4 5
5
решение1
Вам необходимо установить счетчик глобально.
Обратите внимание, что это \newcount\N
определенно не относится к тексту замены для \example
.
\documentclass{article}
\newcount\N
\newcommand\example{%
\global\N=0
\loop
{\loop
\the\N\quad
\ifnum\N<5
\global\advance\N by 1
\repeat
}%
\par
\the\N\par
\ifnum\N<5
\global\advance\N by 1
\repeat
}
\begin{document}
\example
\end{document}
Кроме того, вы можете использовать \expandafter
для выхода за пределы группы:
\newcount\N
\newcommand\example{%
\N=0
\loop
{\loop
\the\N\quad
\ifnum\N<5
\advance\N by 1
\repeat
\expandafter
}\expandafter\N\the\N\relax
\par
\the\N\par
\ifnum\N<5
\advance\N by 1
\repeat
}
решение2
Если вам не нужно устанавливать значение глобально во внутреннем цикле, то вы можете определить \nogroup
. Суть этой проблемы в следующем: {...}
фигурные скобки имеют два значения: они открывают и закрывают группу и защищают внутренний разделитель для разделенного параметра. Мы хотим использовать их (из-за второго значения), но без открытия/закрытия группы:
\newcount\N
\def\nogroup#1{#1}
\def\example
{%
\loop
\nogroup{\loop
\the\N\quad
\ifnum\N<5
\advance\N by 1
\repeat
}%
\endgraf
\the\N
\endgraf
\ifnum\N<5
\advance\N by 1
\repeat
}
\example
\bye
решение3
Вы можете использовать цикл, не выполняющий присваивания, и, следовательно, не нужно заключать внутренний цикл в пару фигурных скобок, чтобы избежать перезаписи.
Я взял ваш пример в точности (хм... нет, мы не хотим, чтобы \newcount\N
это делалось несколько раз при каждом \example
использовании!) и заменил только два \loop
на \xintloop
. Он предназначен для удаления фигурных скобок, используемых для сокрытия внутреннего, \repeat
поэтому пошаговое выполнение счетчика сохраняется при выходе во внешний цикл.
\documentclass{article}
\usepackage{xinttools}
\begin{document}
\newcount\N
\newcommand\example
{%
\xintloop
{\xintloop
\the\N\quad
\ifnum\N<5
\advance\N by 1
\repeat
}%
\the\N
\ifnum\N<5
\advance\N by 1
\repeat
}
\example
\end{document}