\let 使用指標嗎?

\let 使用指標嗎?

是否\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}

在此輸入影像描述

相關內容