当 \A、\B 和 \C 作为参数时,为什么 \renewcommand{\A}{\B} 会改变 \C? 的值?

当 \A、\B 和 \C 作为参数时,为什么 \renewcommand{\A}{\B} 会改变 \C? 的值?

我对以两个宏作为参数的命令似乎会影响第三个宏的值的效果感到非常困惑\renewcommand。这一切都发生在一个命令中,所有三个宏都作为参数传递给该命令。这是一个 MWE;我打印了相关变量的中间值以隔离“问题”发生的位置:

\documentclass{article}
\usepackage{color}
\newcommand{\mA}{3.1}
\newcommand{\mB}{0}
\newcommand{\mC}{8.2}
\newcommand{\saveSwapValue}[3]{%
\noindent
Before executing either \texttt{\textbackslash{}renewcommand}:\\
\#1: #1\\
\#2: #2\\
\#3: #3\\
    \renewcommand{#2}{#1}
After \texttt{\textbackslash{}renewcommand\{\#2\}\{\#1\}}  \\
\#1: #1\\
\#2: #2\\
\#3: #3\\
    \renewcommand{#1}{#3}
After \texttt{\textbackslash{}renewcommand\{\#1\}\{\#3\}}  \\
\#1: #1\\
\textcolor{red}{\#2: #2}\\
\#3: #3\\
}
\begin{document}
\saveSwapValue{\mA}{\mB}{\mC}
\texttt{\textbackslash{}mB}: \mB.\\
\end{document}

输出如下:

在此处输入图片描述

意外结果以红色突出显示:第二个参数的值\mB被 更改\renewcommand{\mA}{\mC}。我原本以为\mB不会受到第二个 的影响\renewcommand

如果能够帮助我了解我所不理解的地方我将非常感激!

答案1

请记住\renewcommand{<cmd>}{<stuff>},任何后续使用<cmd>被取代<stuff>换个角度来看,用一个更实际的例子来说,

\renewcommand{\mB}{\mA}

每次调用 时,都会用 替换\mB-\mA而不是存储在 中的任何内容。这是因为 (La)TeX 不会\mA\mB扩张使用时\mA(重新) 定义时的值。\mB\renewcommand

因此,以下\renewcommand{\mB}{\mA}(之后->应解释为扩张),

\mA -> 3.1
\mB -> \mA -> 3.1

然后\renewcommand{\mA}{\mC}

\mA -> \mC -> 8.2
\mB -> \mA -> \mC -> 8.2
\mC -> 8.2

如果你想复制\mA的值\mB(在扩展时尚),那么你可以尝试\edef或者\let代替:

在此处输入图片描述

\documentclass{article}

\usepackage{xcolor}

\newcommand{\saveSwapValueA}[3]{%
  \noindent
  Before executing either \texttt{\string\renewcommand}: \\
  \#1: \texttt{\string#1}: #1 \\
  \#2: \texttt{\string#2}: #2 \\
  \#3: \texttt{\string#3}: #3 \\
      \renewcommand{#2}{#1}
  After \texttt{\string\renewcommand\string{\string#2\string}\string{\string#1\string}}: \\
  \#1: \texttt{\string#1}: #1 \\
  \#2: \texttt{\string#2}: #2 \\
  \#3: \texttt{\string#3}: #3 \\
      \renewcommand{#1}{#3}
  After \texttt{\string\renewcommand\string{\string#1\string}\string{\string#3\string}}: \\
  \#1: \texttt{\string#1}: #1 \\
  \textcolor{red}{\#2: \texttt{\string#2}: #2} \\
  \#3: \texttt{\string#3}: #3 \\
}

\newcommand{\saveSwapValueB}[3]{%
  \noindent
  Before executing either \texttt{\string\let}: \\
  \#1: \texttt{\string#1}: #1 \\
  \#2: \texttt{\string#2}: #2 \\
  \#3: \texttt{\string#3}: #3 \\
      \let#2=#1
  After \texttt{\string\let\string#2=\string#1}: \\
  \#1: \texttt{\string#1}: #1 \\
  \#2: \texttt{\string#2}: #2 \\
  \#3: \texttt{\string#3}: #3 \\
      \let#1=#3
  After \texttt{\string\let\string#1=\string#3}: \\
  \#1: \texttt{\string#1}: #1 \\
  \textcolor{red}{\#2: \texttt{\string#2}: #2} \\
  \#3: \texttt{\string#3}: #3 \\
}

\begin{document}

\newcommand{\mA}{3.1}
\newcommand{\mB}{0}
\newcommand{\mC}{8.2}

\saveSwapValueA{\mA}{\mB}{\mC}

\renewcommand{\mA}{3.1}
\renewcommand{\mB}{0}
\renewcommand{\mC}{8.2}

\saveSwapValueB{\mA}{\mB}{\mC}

\end{document}

相关内容