这个论坛帮助我理解了如何在 TeX 中使用嵌套循环,但现在我在使用\iftoggle
(来自etoolbox
包的)循环时遇到了麻烦。我的目标是有一个切换开关,它可以在循环进行时跟踪“偶数”或“奇数”状态,其中状态由循环内的代码更新。但是,下面显示的示例没有按我预期的方式工作,因为每次回到外循环时,切换开关似乎都会设置为“偶数”。为什么会发生这种情况,我该如何防止它/有什么更好的方法来实现此功能?
\documentclass{book}
\usepackage{etoolbox}
\begin{document}
\newcount\X
\newcount\Y
\newtoggle{even}
\toggletrue{even}
\loop
\Y = 0
\advance \X by 1
{%
\loop
\advance \Y by 1
\message{\the\X,\the\Y}
\iftoggle{even}{%
\message{EVEN}%
\togglefalse{even}%
}{%
\message{ODD}%
\toggletrue{even}%
}%
\ifnum \Y < 3
\repeat
}%
\ifnum \X < 6
\repeat
\end{document}
输出(注意重复的EVEN
s):
1,1 偶数 1,2 奇数 1,3 偶数 2,1 偶数 2,2 奇数 2,3 偶数 3,1 偶数 3,2 奇数 3,3 偶数 4,1 偶数 4,2 奇数 4,3 偶数 5,1 偶数 5,2 奇数 5,3 偶数 6,1 偶数 6,2 奇数 6,3 偶数
答案1
这与切换开关的作用域有关。也就是说,在内循环中,对\toggletrue
和 的调用\togglefalse
是有效的,但一旦完成就会被忽略,恢复为原始定义\toggletrue{even}
。这就是为什么 then 输出是EVEN
用于每个内循环的开始。为了让这些重新定义在整个范围内保持不变,请在切换开关前面加上\global
:
...
\global\togglefalse{even}%
...
\global\toggletrue{even}%
...
这是我进行上述更改后得到的输出:
1,1 EVEN 1,2 ODD 1,3 EVEN 2,1 ODD 2,2 EVEN 2,3 ODD 3,1 EVEN 3,2 ODD 3,3 EVEN 4, 1 ODD 4,2 EVEN 4,3 ODD 5,1 EVEN 5,2 ODD 5,3 EVEN 6,1 ODD 6,2 EVEN 6,3 ODD
答案2
你必须在和\global
前面写。\togglefalse{even}
\toggletrue{even}
答案3
如果你使用etoolbox
,那么你应该使用\whileboolexpr
。也许可以使用\newcounter{X}
,\value{X}
而不是\newcount\X
。\X
因此:
\documentclass{minimal}
\usepackage{etoolbox}
\begin{document}
\newcounter{X}
\newcounter{Y}
\newtoggle{even}
\toggletrue{even}
\setcounter{X}{0}
\whileboolexpr{test {\ifnumcomp{\value{X}}<6} }{%
\stepcounter{X}
\setcounter{Y}{0}
\whileboolexpr{test {\ifnumcomp{\value{Y}}<3} }{%
\stepcounter{Y}
\arabic{X}, \arabic{Y}:
\iftoggle{even}%
{EVEN\togglefalse{even}}%
{ODD\toggletrue{even}}\par
}%
}
\end{document}
我删除了多余的内循环组,只需重置\Y=0
它就可以工作。你会发现它看起来像其他编程语言中常见的 for 循环。