使用 tikz 创建控制流图?

使用 tikz 创建控制流图?

我正在尝试在我的一篇论文中为某个算法集成一个美观的控制流图:

static void PrintEven(int x)
{
    int c = 0;
    while (c <= x)
    {
        if (c % 2 == 0)
            Console.WriteLine(c);
        c++;
    }
    Console.WriteLine("Done.");
}

我首先创建了 cfghttp://www.webgraphviz.com/看起来太可怕了:

在此处输入图片描述

我被告知要用 tikz 创建图表,这样看起来会更好。我被告知这是在论文中实现 CFG 的首选方法。所谓好看,是指一个漂亮的垂直结构,入口节点位于顶部,出口节点(Console.WriteLine("Done"))位于底部。此外,如果箭头不是圆形的,而是看起来像这张图片中那样,那就太好了:

在此处输入图片描述

有人能告诉我如何使用 tikz 为我的算法创建 CFG 吗?

答案1

这不一定是一个答案,而是一种试图将上述讨论引向不同方向的尝试。此站点上有很多流程图类型的图表。一个很好的例子是这个答案,我在这里添加了一个略微的变化。(请注意,我不是程序员,因此我很可能对该流程图的元素使用了错误的样式。这是将其设为社区 wiki 的另一个原因。)

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{positioning}
\usetikzlibrary{shapes.geometric}
\begin{document}
\begin{tikzpicture}[node distance=1cm,font=\sffamily,
    startstop/.style={rectangle, rounded corners, minimum width=3cm, minimum height=1cm,text centered, draw=black, fill=red!30},
    process/.style={rectangle, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=orange!30},
    io/.style={trapezium, trapezium left angle=70, trapezium right angle=110, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=blue!30},
    decision/.style={diamond, minimum width=3cm, minimum height=1cm, text centered, draw=black, fill=green!30},
    arr/.style={very thick,-latex}
    ]
    \node (int) [startstop]                             {\texttt{int c=0;}};
    \node (while) [process,below=of int]  {\texttt{while (c <= x)}};
    \draw[arr] (int) -- (while);
    \node (if) [decision,below=of while]        {\texttt{if (c \% 2 == 0)}};       
    \draw[arr] (while) -- (if);
    \node (write) [process,right=of if] {\texttt{Console.WriteLine(c);}};
    \draw[arr] (if) -- (write) node[midway,above]{yes};
    \node (pp) [process,below=of if]  {\texttt{c++;}};
    \draw[arr] (if) -- (pp) node[midway,left]{no};
    \draw[arr] (write) |- (pp);
    \draw[arr] (pp.west) -- ++ (-1,0) |- (while) node[pos=0.25,left]{$c\le x$};
\end{tikzpicture}
\end{document}

在此处输入图片描述

这里我还有一个“替代方案”......(......“替代方案”似乎意味着一个人从另一篇文章中复制而不提及它,保留 90% 并在这里和那里做一些小的修改。好的,那么这是一个“替代方案”,;-)

\documentclass[tikz,border=3.14mm]{standalone}
\usetikzlibrary{positioning,shapes.geometric}
\begin{document}
\begin{tikzpicture}[node distance = 9mm and 14mm,
    nodes= {draw, minimum width=8em, minimum height=2em,
                    font=\ttfamily},
startstop/.style = {fill=red!30, rounded corners},
  process/.style = {fill=orange!30},
       io/.style = {fill=blue!30,
                    trapezium, trapezium stretches body,
                    trapezium left angle=70, trapezium right angle=110},
 decision/.style = {fill=green!30, diamond, aspect=1.5},
 exp/.style={draw=none,font=\sffamily,minimum width=1em},
      arr/.style = {very thick,-latex}
    ]
\node (int) [io]    {int c=0;};
\node (while) [process,below=of int]    {while (c <= x)};
\draw[arr] (int) -- (while);
\node (if) [decision,below=of while]    {if (c \% 2 == 0)};
\draw[arr] (while) --  node[exp,right]  {$c\le x$} (if);
\node (write)   [process,below=of if]   {Console.WriteLine(c);};
\draw[arr] (if) --  (write) node[exp,pos=0.5,left] {yes};
\node (pp)      [process,below=of write]    {c++;};
\draw[arr] (write) -- (pp);
\draw[arr] (if.east)  --  ++ (1,0) node[exp,pos=0.5,above] {no} |- (pp) ;
\node (done)   [startstop,below right=of write]   {Console.WriteLine("Done");};
\draw[arr] (while) -| (done)   node[exp,pos=0.25,above] {$c> x$};
\draw[arr] (pp.west) -- ++ (-1,0) |- (while);
\end{tikzpicture}
\end{document}

在此处输入图片描述

答案2

基于我的一个旧解决方案回答类似问题。与之相比,下面的 MWE 尝试复制您问题中的第一个图像:

在此处输入图片描述

\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{positioning,
                shapes.geometric}

\begin{document}
    \begin{tikzpicture}[
   node distance = 8mm and 12mm,
     base/.style = {draw, fill=#1,
                    minimum width=28mm, minimum height=7mm,
                    font=\ttfamily},
startstop/.style = {base=red!30, rounded corners},
  process/.style = {base=orange!30},
       io/.style = {base=blue!30,
                    trapezium, trapezium stretches body,
                    trapezium left angle=70, trapezium right angle=110},
 decision/.style = {base=green!30, diamond, aspect=1.5},
      arr/.style = {semithick,-latex}
    ]
\node (int) [io]    {int c=0;};
\node (while) [process,below=of int]    {while (c <= x)};
    \draw[arr] (int) -- (while);
\node (if) [decision,below=of while]    {if (c \% 2 == 0)};
    \draw[arr] (while) --  node[right]  {$c\le x$} (if);
\node (write)   [process,below=of if]   {Console.WriteLine(c);};
    \draw[arr] (if) -- node[left] {yes} (write);
\node (pp)      [process,below=of write]    {c++;};
    \draw[arr] (write) -- (pp);
    \draw[arr] (if.east)  -- node[above] {no} ++ (1,0) |- (pp);
\node (done)   [startstop,
                below right=of write]   {Console.WriteLine("Done");};
    \draw[arr] (while) -| (done)   node[pos=0.25,above] {$c> x$};
    \draw[arr] (pp.west) -- ++ (-1,0) |- (while);
\end{tikzpicture}
\end{document}

相关内容