¿Cómo puedo dibujar flechas dentro de un listado para explicar la asociación posicional?

¿Cómo puedo dibujar flechas dentro de un listado para explicar la asociación posicional?

Necesito un buen dibujo en lstlistingcódigo C/C++. Estoy intentando hacer algo como esto explicación de la función printf

Esto es lo que he hecho hasta ahora.

ingrese la descripción de la imagen aquí

\documentclass[11pt]{article}
\usepackage{listingsutf8}
\usepackage{tikz}
\usetikzlibrary{decorations.text}
 \newcommand{\tikzmark}[2]{%
     \tikz[overlay,remember picture] \node[text=black,
           inner sep=2pt] (#1) {#2};}
\begin{document}
\begin{lstlisting}[language=c,escapeinside={(*@}{@*)}]
#include <stdio.h>
int main (void)
{
int value1, value2, sum;//declaring
value1 = 50;//assign values
value2 = 25;
sum = value1 + value2;//sum them
//output
printf ("%d(*@\tikzmark{a}{} @*)+%d(*@\tikzmark{b}{} @*)= %d(*@\tikzmark{c}{} @*)\n", value1(*@\tikzmark{a1}{} @*), value2(*@\tikzmark{b1}{} @*), sum(*@\tikzmark{c1}{} @*));
 (*@
\begin{tikzpicture}[overlay,remember picture]
 \node (a) at (a.{east}) {};
\node  (a1) at (a1.{north west}) {};
\node  (b) at (b.{east}) {};
\node  (b1) at (b1.{north west}) {};
\node  (c) at (c.{east}) {};
\node  (c1) at (c1.{north west}) {};        
\draw[->,red,in=120,out=100] (a1) to (a);
\draw[->,red,in=120,out=100] (b1) to (b);
\draw[->,red,in=120,out=100] (c1) to (c);
\end{tikzpicture}
 @*)
    return 0;
 }
 \end{lstlisting}
\end{document}

¿Cómo hacer que los nodos y las flechas de tikz sean más bonitos?

Respuesta1

Puede ajustar los ángulos iny out, así como cambiar la ubicación de los puntos inicial y final:

ingrese la descripción de la imagen aquí

Notas:

  • También agregué basicstyle=\ttfamilypara tener una listingssalida más parecida.
  • \tikzmarkSe añadió una a la izquierda.yderecha de cada marca para simplificar los cálculos de los puntos medios.

Código:

\documentclass[11pt]{article}
\usepackage{listingsutf8}
\usepackage{tikz}
\usetikzlibrary{decorations.text,calc}
 \newcommand{\tikzmark}[2]{%
     \tikz[overlay,remember picture] \node[text=black,
           inner sep=2pt] (#1) {#2};}


\newcommand{\VerticalShiftForArrows}{0.0em,+2.75ex}%
\newcommand{\VerticalShiftForBar}{0.0em,+2.0ex}%
\newcommand{\Stub}{0.0em,-0.6ex}%
\newcommand{\DrawOverBar}[3][]{%
        \coordinate (top left)  at ($(#2)       +(\VerticalShiftForBar)$);
        \coordinate (start)     at ($(top left) +(\Stub)$);
        \coordinate (top right) at ($(#3)       +(\VerticalShiftForBar)$);
        \coordinate (end)       at ($(top right)+(\Stub)$);
        \draw [#1] (start) -- (top left) -- (top right) -- (end);
}%
\newcommand{\DrawArrows}[3][]{%
    \coordinate (Start Mid) at ($(#2Left)!0.5!(#2Right) + (\VerticalShiftForArrows)$);
    \coordinate (End Mid)   at ($(#3Left)!0.5!(#3Right) + (\VerticalShiftForArrows)$);
    
    \draw[-stealth, thick, #1] (Start Mid) to (End Mid);
}

\begin{document}
\begin{lstlisting}[language=c,escapeinside={(*@}{@*)},basicstyle=\ttfamily]
#include <stdio.h>
int main (void)
{
int value1, value2, sum;//declaring
value1 = 50;//assign values
value2 = 25;
sum = value1 + value2;//sum them
//output
printf ("(*@\tikzmark{aLeft}{}@*)%d(*@\tikzmark{aRight}{}@*)+(*@\tikzmark{bLeft}{}@*)%d(*@\tikzmark{bRight}{}@*)= (*@\tikzmark{cLeft}{}@*)%d(*@\tikzmark{cRight}{}@*)\n", (*@\tikzmark{value1Left}{}@*)value1(*@\tikzmark{value1Right}{}@*), (*@\tikzmark{value2Left}{}@*)value2(*@\tikzmark{value2Right}{}@*), (*@\tikzmark{sumLeft}{}@*)sum(*@\tikzmark{sumRight}{}@*));
 (*@
\begin{tikzpicture}[overlay,remember picture]
    \foreach \x/\y in {a/red, c/blue, value1/red, sum/blue} {
        \DrawOverBar[-, \y, thick]{\x Left.north}{\x Right.north}
    }
    
    \foreach \x/\y in {b/brown, value2/brown} {% Needs special handling as we are putting this below
        \renewcommand{\VerticalShiftForBar}{0.0em,-0.8ex}%
        \renewcommand{\Stub}{0.0em,+0.6ex}%
        \DrawOverBar[-, \y, thick]{\x Left.south}{\x Right.south}
    }
    
    \DrawArrows[red,   in=20,  out=160]{value1}{a}
    \DrawArrows[blue,  in=30,  out=150, distance=6.5ex]{sum}{c}
    
    \renewcommand{\VerticalShiftForArrows}{0.0em,-2.0ex}%Needs special handling as we are putting this below
    \DrawArrows[brown, in=-30, out=-150]{value2}{b}
        
\end{tikzpicture}
 @*)
    return 0;
 }
 \end{lstlisting}
\end{document}

información relacionada