
是否\let
真的創建了一個新的控制序列,或者只是將一個指標分配給一個已經定義的控制序列?
高德納說:
let\cs=<token>
給予\cs
標記的當前意義。如果<token>
是另一個控制序列,\cs
則將獲得與該控制序列相同的意義。 (課本206)
假設我定義一個新的清單環境bars
,其中\bar
只是另一個名稱\item
:
\newenvironment{bars}
{\begin{enumerate}\let\bar\item}
{\end{enumerate}}
然後在我的文件中使用該環境 1000 次,如下所示:
\begin{bars}
\bar bla bla
\bar bla bla bla
\end{bars}
記憶體中有多少位置最終具有與\item
編譯文件時相同的內容? 1、2 還是 1001?
答案1
你的問題的答案是“還有一個”,即\item
和\bar
(所以,總共兩個)。
工作方式\let\a<token>
是將 的含義逐字複製<token>
到控制序列中\a
,以便每當\a
「執行」時,它的行為就像<token>
在那裡一樣。這種複製是在指令發出時完成的\let
,因此無論\a
使用多少次,都不會進行新的更改;此外,如果<token>
改變它是的意義(例如,透過另一個\let
), 的意義\a
不受影響。
從某種意義上說,您使用術語“指針”是不合適的,因為 TeX 作為一種語言沒有內存模型,它實現的語言也(不一定)可以隨機訪問它是記憶體模型,其實現的內部細節也與理解其操作無關。然而,即使假設 TeX 是用(例如)C 實現的,指向令牌的指標的類似物將是
\def\a{<token>}
*\a = <token>
假設這是有效的 C 語法,就像。想像的語法*\a = *<token>
對應於\let\a<token>
,而語法*\a = <token>
,雖然與第一個類似,但實際上會以\a
這樣的方式定義:\def\a{<other token>}
重新定義 <token>
,這在 TeX 中是不可能的。所以 TeX 中並沒有與指針完全類似的東西。
答案2
儘管 TeX 可以存儲給定宏的多個版本(位於 { } 組的本地),但通常很難填滿內存,因為一旦離開該組,內存就會被回收並重用(這是我最初評論的基礎) )。大多數環境(例如 itemize)都包含此類分組。當現有命令被 \def'd 或 \let'd 為群組內的其他命令時,舊版本將被保存(堆疊)並在群組末尾恢復。
除非您管理嵌套群組或類似的無限遞歸,否則任何標準結構都不會產生太多“堆疊”浪費。
可以使用給定巨集的不同定義來產生大量有限數量的巢狀組,但您必須有點狡猾:
\documentclass[a5paper,12pt]{article}
\usepackage[margin=20mm]{geometry}
%% version of plain TeX \loop that uses global macros
\def\gloop#1\repeat{\gdef\body{#1}\giterate}
\def\giterate{\body \global\let\next\giterate \else\global\let\next\relax\fi \next}
\let\repeat=\fi % this makes \loop...\if...\repeat skippable
\begin{document}
\raggedright
\section*{Ascending}
\newcount\n
\global\n=0
\gloop
\ifnum \n<100
\bgroup
\edef\foo{\the\n}
\let\baz=\foo
\global\let\foobar=\baz
$\foo^{\baz}_{\foobar} \uparrow$
\global\advance\n 1
\repeat
\section*{Descending}
\global\n=0
\gloop
\ifnum \n<100
$\foo^{\baz}_{\foobar} \downarrow$
\egroup
\global\advance\n 1
\repeat
\end{document}