\if 是如何处理?

\if 是如何处理?

以下示例如果为假 且 之前未初始化,\def\a...则失败。相反,如果为真,则 可以在 之前或 之后初始化。\ifabc\myif\def\a...\ifabc\myif\def\a...

我不清楚为什么当\ifabc为真且\myif之前未初始化时它不会失败\def\a

\newif\ifabc
\abctrue % \abcfalse

%\let\myif=\iftrue

\ifabc
  \def\a#1#2{\myif#1\else#2\fi}
\fi

%\let\myif\iftrue

\ifabc
  \a{hello}{world}
\fi

\end

答案1

这是对cfr 的答案

TeX Book 在第 20 章中提到了以下内容定义(也称为宏)(第 210 页)

请注意,所有条件控制序列都以 开头\if...,并且都有一个匹配的\fi。这种约定 - 即 和\if...配对\fi- 使您更容易看到程序中条件的嵌套。 的嵌套\if...\fi独立于 的嵌套{...};因此,您可以在条件的中间开始或结束一个组,也可以在组的中间开始或结束一个条件。丰富的宏使用经验表明,这种独立性在应用程序中非常重要;但如果您不小心,它也会导致混乱。

嗯...大家要小心。:)请注意,您有一种嵌套\if...\fi和分组的形式{...}

另见(第 213 页):

\if...扩展时,TeX 会尽可能向前读取,以确定条件是真还是假;如果为假,它会向前跳过(跟踪\if...\fi嵌套),直到找到\else\or\fi来结束跳过的文本。同样,当\else\or\fi扩展时,TeX 会读取到任何应该跳过的文本的末尾。

根据以上信息,我们发现在 下\abcfalse,TeX“跳过 ... 直到找到\else结束跳过文本的 ...”,而不考虑任何分组。因此,扩展以#2在垂直模式下评估宏参数结束。

我们还可以使用追踪(某种程度上)发生了什么:

 1: \documentclass{article}
 2: 
 3: \begin{document}
 4: 
 5: \newif\ifabc% Default is \abcfalse
 6: 
 7: %\let\myif=\iftrue
 8: 
 9: \tracingifs1
10: \ifabc
11:   \def\a#1#2{\myif#1\else#2\fi}
12: \fi
13: 
14: %\let\myif\iftrue
15: 
16: \ifabc
17:   \a{hello}{world}
18: \fi
19: 
20: test
21: 
22: \end{document}

跟踪结果\else显示(仍处于垂直模式)位于第 10 行的语句中\if...

{vertical mode: \iffalse: (level 1) entered on line 10}
{\else: \iffalse (level 1) entered on line 10}

! You can't use `macro parameter character #' in vertical mode.
l.11   \def\a#1#2{\myif#1\else#
                               2\fi}
Sorry, but I'm not programmed to handle this case;
I'll just pretend that you didn't ask for it.
If you're in the wrong mode, you might be able to
return to the right one by typing `I}' or `I$' or `I\par'.

答案2

思考...

... 当 时\abctrue,条件成立,所以\def执行。因此,TeX 不会尝试执行 的内容,\def直到实际使用宏为止。

但是,当 时\abcfalse,它必须通读 的内容来\def寻找\else。由于\myif不是条件语句,因此它无法意识到 是\else嵌套的。因此,它会读取 之后的内容\else作为它要执行的内容,因为\abcfalse。这会失败,因为#2不能在这里使用。

尝试

\def\a#1#2{\myif#1\else\show\super#2\fi}% but not for real - never \def a single letter macro name unless you are really, really sure you want to overwrite anything it alreay means.

看看发生了什么:

> \super=undefined.
l.153   \def\a#1#2{\myif#1\else\show\super
                                          #2\fi}
? 
! You can't use `macro parameter character #' in vertical mode.
l.153   \def\a#1#2{\myif#1\else\show\super#
                                           2\fi}

相反,如果您在and set\show\super之前有,那么除非您实际使用了定义的宏,否则它将永远不会被执行。\else\abctrue

相关内容