ifx、宏和分组

ifx、宏和分组

我不明白 \ifx 如何与宏定义交互。这是一个最小的例子:

\def\a#1{\b}
\def\b#1#2{[#1:#2]}
\a ABC

输出结果与预期一致。如果我将[B:C]的定义更改为\a

\def\a#1{\ifx E#1\else \b\fi}

然后输出变成[:B]C。空参数从何而来\b,我该如何摆脱它?

我很抱歉问了一个之前肯定有人在这个网站上问过的问题。我努力寻找答案,但徒劳无功。谢谢!

答案1

\def\a#1{\ifx E#1\else \b\fi}

调用\a ABCA作为参数\a,因此输入流变为

\ifx EA\else\b\fi BC

并且由于条件为假,输入流中剩余的是

\b\fi BC

因此的参数\b#1<-\fi#2<-B,所以我们得到

[\fi:B]C

现在\fi履行消失的义务,你得到

[:B]C

如果你定义

\def\a#1{\ifx E#1\else\expandafter\b\fi}

经过条件判断后我们得到

\expandafter\b\fi BC

\expandafter产品\fi消失 \b被展开,所以我们发现

\b BC

最后

[B:C]

在这种情况下\a EBC,第一步将得到

\ifx EE\else\b\fi BC

变成

\else\b\fi BC

的扩展\else会抛弃匹配之前的所有内容\fi,我们只需得到

BC

查看日志文件有助于\tracingmacros=1

\tracingmacros=1
\def\a#1{\ifx E#1\else \b\fi}
\def\b#1#2{[#1:#2]}
\a ABC

将产生

\a #1->\ifx E#1\else \b \fi 
#1<-A

\b #1#2->[#1:#2]
#1<-\fi 
#2<-B

这准确地表明了我无需进行实验就做出的诊断。

如果你还添加\tracingifs=1(使用基于 e-TeX 的引擎,例如pdftex),你会得到

\a #1->\ifx E#1\else \b \fi 
#1<-A
{vertical mode: \ifx: (level 1) entered on line 4}
{\else: \ifx (level 1) entered on line 4}

\b #1#2->[#1:#2]
#1<-\fi 
#2<-B
{horizontal mode: \fi: \ifx (level 1) entered on line 4}

答案2

\b抓住\fi但如果您使用以下定义\a,您将获得预期的输出:

\def\a#1{\ifx E#1\else \expandafter\b\fi}

以上完成了\if..\fi处理之前的条件\b

在此处输入图片描述

\documentclass{article}
\begin{document}

\def\a#1{\b}
\def\b#1#2{[#1:#2]}
\a ABC

\def\a#1{\ifx E#1\else \b\fi}
\a ABC

\def\a#1{\ifx E#1\else \expandafter\b\fi}
\a ABC

\end{document}​

如果您希望看到这一点,请使用以下的定义\b并检查和.log中包含的值:\argA\argB

\def\b#1#2{%
  \def\argA{#1}\show\argA%
  \def\argB{#2}\show\argB%
  [#1:#2]}

对于上面的第二次调用\a,你会发现

> \argA: macro
-> \fi .
> \argB: macro
-> B.

相关内容