对于一篇论文,我必须提供两个执行相同操作的代码片段来比较它们。
我开始将它们放在两个不同的图形中,但现在,我试图将它们并排放置,而这正是麻烦的开始。
首先,我似乎无法让列表在 subfig 中工作。
\lstset{%
language=C,
frame=single,
numbers=left,
numberstyle=\footnotesize,
tabsize=2,
keepspaces=true,
columns=fullflexible,
basicstyle=\ttfamily,
keywordstyle=\color{blue}
}
\begin{figure}
\subfloat[small code]{%
\begin{lstlisting}
for(int i = 0 ; i < N ; i++)
for(int j = 0 ; j < N ; j++)
for(int k = 0 ; k < N ; k++)
c[i][j] += a[i][k] * b[k][j];
\end{lstlisting}
}
\hfill
\subfloat[Larger code]{%
\begin{lstlisting}
for(int ii = 0 ; ii < N ; ii+=B) {
for(int jj = 0 ; jj < N ; jj+=B) {
for(int kk = 0 ; kk < N ; kk+=B) {
for(int i = ii ; i < ii + B ; i++) {
for(int k = kk ; k < kk + B ; k++){
c_i = c[i];
a_ik = a[i][k];
b_k = b[k];
for(int j = jj ; j < jj + B ; j+=2){
c_i[j] += a_ik * b_k[j];
c_i[j+1] += a_ik * b_k[j+1];
}
}
}
}
}
}
\end{lstlisting}
}
\end{figure}
这会产生很多我无法理解的错误。浏览网页后,我发现很多人似乎通过包含外部文件的源代码来实现我想要做的事情。
\begin{figure}[!htb]
\subfloat[Toto]{%
\lstinputlisting{mm_base.c}%
}
\hfill
\subfloat[Tata]{%
\lstinputlisting{mm_opt.c}%
}
\end{figure}
通过手动更改字体大小,我可以让子浮点数并排,但得到以下结果:
代码周围的框架和内容的感知大小似乎不匹配。此外,右侧的代码超出了范围,右侧框架超出了页面范围。
我想知道的第一件事,实际上是出于好奇,为什么我不能使用 lstlisting 环境,而只能在子浮点数内部使用 lstinputlisting。
而更紧迫的事情是让框架与子图的宽度相匹配。而更具挑战性的部分可能是自动更改所包含代码的大小以适合子图。
答案1
您需要\linewidth
在使用之前减少\lstinputlisting
,否则它会使用完整的正常线宽。
您可以使用\parbox
或minipage
环境执行此操作。例如,以下代码将列表放置在具有正常行宽 48% 的段落框中。(有些人使用\textwidth
大致相同的。)
\parbox{.48\linewidth}{\lstinputlisting{file.c}}
你的第一个示例不起作用的原因是,这lstlisting
是一个逐字环境,因此不允许在其他宏的参数中使用。这是因为在处理之前,代码是作为参数的一部分读取的\begin{lstlisting}
,并告诉 LaTeX 逐字地线程化代码!
如果您希望将代码放在主文件中,则可以将列表存储在一个框中,然后在中使用\subfloat
。这需要minipage
因为\parbox
还会将列表读取为宏参数。
\documentclass{article}
\usepackage{xcolor}
\usepackage{subfig}
\usepackage{listings}
\lstset{%
language=C,
frame=single,
numbers=left,
numberstyle=\footnotesize,
tabsize=2,
keepspaces=true,
columns=fullflexible,
basicstyle=\ttfamily\scriptsize,
keywordstyle=\color{blue}
}
\newsavebox{\mylistingbox}
\begin{document}
\begin{figure}
\begin{lrbox}{\mylistingbox}%
\begin{minipage}{.45\linewidth}%
\begin{lstlisting}
for(int i = 0 ; i < N ; i++)
for(int j = 0 ; j < N ; j++)
for(int k = 0 ; k < N ; k++)
c[i][j] += a[i][k] * b[k][j];
\end{lstlisting}%
\end{minipage}%
\end{lrbox}%
%
\subfloat[small code]{\usebox{\mylistingbox}}%
%
\hfill
%
\begin{lrbox}{\mylistingbox}%
\begin{minipage}{.45\linewidth}%
\begin{lstlisting}
for(int ii = 0 ; ii < N ; ii+=B) {
for(int jj = 0 ; jj < N ; jj+=B) {
for(int kk = 0 ; kk < N ; kk+=B) {
for(int i = ii ; i < ii + B ; i++) {
for(int k = kk ; k < kk + B ; k++){
c_i = c[i];
a_ik = a[i][k];
b_k = b[k];
for(int j = jj ; j < jj + B ; j+=2){
c_i[j] += a_ik * b_k[j];
c_i[j+1] += a_ik * b_k[j+1];
}
}
}
}
}
}
\end{lstlisting}%
\end{minipage}%
\end{lrbox}%
%
\subfloat[Larger code]{\usebox{\mylistingbox}}%
\end{figure}
\end{document}
我在这里缩小字体大小以适应正常文本宽度。对于图形,您还可以使用我在中心图形的宽度大于 \textwidth和将图表并排摆放,溢出到外边距。在您的情况下,要么使用两个盒子寄存器,然后:
\makebox[1.2\textwidth]{\subfloat[Shorter code]{\usebox{\mylistingboxa}}\hfill\subfloat[Larger code]{\usebox{\mylistingboxb}}}
或者在整个 subfloat 相关代码之前和之后添加以下等效行:
\hbox to 1.2\textwidth\bgroup\hss
% the whole box saving and \subfloat code above
\hss\egroup