![Tex 容量超出范围(如果在使用宏后删除%)](https://linux22.com/image/237959/Tex%20%E5%AE%B9%E9%87%8F%E8%B6%85%E5%87%BA%E8%8C%83%E5%9B%B4%EF%BC%88%E5%A6%82%E6%9E%9C%E5%9C%A8%E4%BD%BF%E7%94%A8%E5%AE%8F%E5%90%8E%E5%88%A0%E9%99%A4%25%EF%BC%89.png)
我不明白为什么如果我删除对 的调用后的TeX capacity exceeded, sorry [main memory size=3000000]
最后一个 ,这个简单(但冗长)的迭代会导致。我认为在使用宏后不需要 %。%
\DoNothing
\documentclass{article}
\usepackage{pgfplots}
\newcommand{\DoNothing}[4]{}
\begin{document}
Processing....
\foreach \i in {1,2,3} {%
\foreach \j in {1,2,3,...,11} {%
\foreach \k in {1,2,...,100}{%
\DoNothing{}{}{}{}
\foreach \a in {1,2,3,...,9} {%
\DoNothing{}{}{}{}
\foreach \b in {1,2,3,...,9} {%
\DoNothing{}{}{}{}%
}
}
}
}
}
\end{document}
这将按原样运行,但如果%
删除最后一个则不会运行。
答案1
TeX 将输入文件中的所有空格解释为单个“空格”字符,但有两个例外:
\macro
“控制字”(例如但不类似于名称\'
不是单词的重音产生宏的宏)结束后的空格将被忽略;注释后的任何内容都会被忽略,包括换行符(以及下一行开头的空格)。
在您的代码中,如果没有%
,对 的调用后面\DoNothing
会跟着一个未加保护的换行符,TeX 会将其解释为空格。尽管\DoNothing
是一个宏,但情况也是如此,因为空格只会被忽略直接地控制字之后,并且\DoNothing
中间有四个参数。
最后的每次迭代\foreach
都会贡献一个这样的空间,这些越来越长的空格字符串会反馈给前面的\foreach
's 作为它们的循环体。这不是唯一一个贡献该字符串的空间,因为实际上大多数换行符(包括\DoNothing
括号后和括号后)都没有保护,而且看起来这个(最内层的循环,因此也是最具破坏性的)只是将参数的长度推到第一个,\foreach
超过了 TeX 可以处理的长度。
在您的代码中,删除所有不需要的空格的方法是编写
\foreach \i in {1,2,3} {%
\foreach \j in {1,2,3,...,11} {%
\foreach \k in {1,2,...,100}{%
\DoNothing{}{}{}{}%
\foreach \a in {1,2,3,...,9} {%
\DoNothing{}{}{}{}%
\foreach \b in {1,2,3,...,9} {%
\DoNothing{}{}{}{}%
}%
}%
}%
}%
}
在这种情况下,每行都应该在末尾添加注释,因为它们都没有以宏名结尾。下面是一个更简短、更具说明性的示例,说明注释何时有用,何时无用:
\documentclass{article}
\begin{document}
\def\Optional#1{%
\ifx[#1\relax
\OptionalYes
\else
(No optional argument) #1
\fi
}
\def\OptionalYes#1]{%
(Optional argument: #1)
}
\Optional text
\Optional[arg] text
\end{document}
(这不是通常解析可选参数的方式。)目前有两行没有以%
或宏名结尾,每行在相应的测试用例中都会产生明显的视觉错误。如果您%
直接在这些行的文本后面放置,错误就会消失。没有的其他行%
也可以,因为 TeX 会忽略宏名结尾后的空格。