\pgPtList
问题来了:为什么下面的代码会在组结束时重置控制序列的含义?
\documentclass[12pt]{article}
\begin{document}
\begingroup
\gdef\pgPtList{}
\edef\pgPtList{8}
pgPtList is: \pgPtList
\edef\pgPtList{8, 5}
pgPtList is: \pgPtList
\endgroup
Empty environment has ended.
pgPtList is: \pgPtList
\end{document}
以下是它产生的输出:
pgPtList is: 8
pgPtList is: 8, 5
Empty environment has ended.
pgPtList is:
我目前的理解是,这与团体的工作方式有关,因此可能的后续问题是:我如何重新定义控制序列,使得团体结束后更改仍然保持不变?
以下是更广泛的背景:我正在尝试排版考试并跟踪每页上的分数,并且我不断更新\pgPtList
以跟踪每页上的分数。在每次考试中,\pgPtList
它都充当另一个创建分数表的命令的默认参数。
每个页面上的点都在一个环境中更新,这就是 reprex 中存在和的enumerate
原因。理想情况下,我希望能够在此环境中更新变量,即使点表命令将在此环境之外调用。\begingroup
\endgroup
\pgPtList
我主要感到困惑的是\edef
和\gdef
。我天真的理解是这些命令旨在使生成的控制序列在当前组之外可访问,但我从上面的代码中获得的输出表明正在发生其他事情。
答案1
\def\macroname<argument specification>{definition}
是一个局部的、标准的定义;\edef\macroname<argument specification>{definition}
是局部的、扩展的定义,即definition
在分配之前扩展\macroname
;\gdef\macroname<argument specification>{definition}
是一个全球性的、标准的定义;\xdef\macroname<argument specification>{definition}
是一个全球性的、扩展的定义。
就你的情况而言,初始定义\gdef\pgPtList{}
做本地组存活。如果没有,则使用\pgPtList
after\endgroup
会导致错误。
但是,的所有后续(重新)定义\pgPtList
都是明确局部的,因此这些更改不会保留下来\endgroup
,并且的含义\pgPtList
将恢复为最初的空定义。
下面的例子可能会有帮助:
\documentclass[12pt]{article}
\begin{document}
\newcounter{tweak}
\setcounter{tweak}{0}
\def\rstatement{Redefinition \thetweak.}
\begingroup
\gdef\pgPtList{Initial, global definition.}
pgPtList is: \pgPtList
\edef\pgPtList{\rstatement}
pgPtList is: \pgPtList ; \stepcounter{tweak}\pgPtList
\def\pgPtList{\rstatement}
pgPtList is: \pgPtList ; \stepcounter{tweak}\pgPtList
\endgroup
Environment has ended.
pgPtList is: \pgPtList
\begingroup
\xdef\pgPtList{\rstatement}
pgPtList is: \pgPtList ; \stepcounter{tweak}\pgPtList
\endgroup
Environment has ended.
pgPtList is: \pgPtList
\begingroup
\gdef\pgPtList{\rstatement}
pgPtList is: \pgPtList ; \stepcounter{tweak}\pgPtList
\endgroup
Environment has ended.
pgPtList is: \pgPtList
\end{document}
注意,\def
确保在使用宏时\gdef
使用\pgPtList
计数器的值,这可能不是定义时的值。tweak
\pgPtList
相反,\edef
确保\xdef
使用定义时\pgfPtList
的计数器值,即使该值在此期间已经发生变化。tweak
另一方面,\def
和\edef
都是局部定义。当前组结束时,它们的效果也随之结束。
相反,\gdef
和\xdef
是全局的。它们一直有效,除非并且直到某个后续的定义\pgfPtList
取代它们,而不管分组如何。