Cicli annidati

  • Creatore
    Topic
  • #35410
    Up
    0
    Down
    ::


    È possibile annidare i cicli ottenuti con \loop\repeat?
    Ho il seguente codice:
    `\documentclass{minimal}

    \newcounter{tempa}
    \newcounter{tempb}
    \setcounter{tempa}{0}
    \setcounter{tempb}{0}

    \begin{document}

    \loop\ifnum\value{tempa}<7\relax
    \thetempa
    \loop\ifnum\value{tempb}<4\relax
    \thetempb\par
    \stepcounter{tempb}
    \repeat
    \stepcounter{tempa}
    \repeat

    \end{document}`
    Mi aspetterei di ottenere il seguente elenco:
    `
    00
    01
    02
    03
    10
    11
    12

    62
    63`
    Sinceramente non capisco… 😥

    LuCa

Visualizzazione 3 filoni di risposte
  • Autore
    Risposte
    • #35411
      Up
      0
      Down
      ::


      L’errore che riporta a terminale è:
      `! Extra \fi.
      \iterate …mpa} \relax \expandafter \iterate \fi

      l.17 \repeat
      `

      LuCa

    • #35412
      Up
      0
      Down
      ::

      È possibile annidare i cicli ottenuti con \loop\repeat?
      Ho il seguente codice:
      `\documentclass{minimal}

      \newcounter{tempa}
      \newcounter{tempb}
      \setcounter{tempa}{0}
      \setcounter{tempb}{0}

      \begin{document}

      \loop\ifnum\value{tempa}<7\relax
      \thetempa
      \loop\ifnum\value{tempb}<4\relax
      \thetempb\par
      \stepcounter{tempb}
      \repeat
      \stepcounter{tempa}
      \repeat

      \end{document}`
      Mi aspetterei di ottenere il seguente elenco:
      `
      00
      01
      02
      03
      10
      11
      12

      62
      63`
      Sinceramente non capisco… 😥

      Eppure dovresti: la macro \loop è delimitata da \repeat, quindi TeX vede qualcosa che non intendi. La soluzione è di mettere il loop interno tra graffe.

      C’è un altro errore nel tuo loop: il valore di tempb non viene riportato a zero quando scatta tempa.
      `\documentclass{minimal}

      \newcounter{tempa}
      \newcounter{tempb}[tempa]

      \begin{document}

      \loop\ifnum\value{tempa}<7
      {\loop\ifnum\value{tempb}<4
      \thetempa\thetempb\par
      \stepcounter{tempb}
      \repeat}
      \stepcounter{tempa}
      \repeat

      \end{document}`
      Ciao
      Enrico

    • #35413
      Up
      0
      Down
      ::


      Eppure ero sicuro di averci provato, prima di scrivere…
      Grazie, come sempre.

      LuCa

    • #35414
      Up
      0
      Down
      ::

      Eppure ero sicuro di averci provato, prima di scrivere…
      Grazie, come sempre.

      TeX non ha un “goto”: quando una riga di testo è digerita sparisce. Perciò \loop è realizzato essenzialmente definendo una macro che contiene tutto il testo fino a \repeat, escluso; questa macro viene eseguita finché la condizione è vera perché richiama sé stessa:
      `\def\loop#1\repeat{\def\iterate{#1\relax\expandafter\iterate\fi}%
      \iterate \let\iterate\relax}
      \let\repeat\fi`
      La macro si chiama sempre \iterate; dopo che è stata definita, viene espansa: l’espansione comincia con il condizionale che viene valutato: se è vero, viene eseguito il codice e viene richiamata \iterate. Alla fine di tutto il valore di \iterate viene annullato.

      Nel caso di un \loop interno (tra graffe), non c’è alcun problema perché il valore di \iterate viene cambiato localmente.

      Il valore di tempb viene modificato durante il \loop interno, ma \stepcounter esegue un’assegnazione globale: per questo devi riportare il valore a zero associando tempb alla lista di azzeramento di tempa.

      L’equivalenza tra \repeat e \fi serve nel caso il \loop sia in un condizionale, per bilanciare l’\if…; questo è il motivo dello strano errore “Extra \fi” che ottenevi.

      Ciao
      Enrico

Visualizzazione 3 filoni di risposte
  • Devi essere connesso per rispondere a questo topic.

Go to top