Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Creare un ciclo for oscillante
Forum - C/C++ - Creare un ciclo for oscillante

Pagine: [ 1 2 3 4 ] Precedente | Prossimo
Avatar
nello79 (Normal User)
Newbie


Messaggi: 7
Iscritto: 09/04/2020

Segnala al moderatore
Postato alle 19:34
Giovedì, 09/04/2020
Salve ragazzi, sono un nuovo iscritto e vi anticipo che sono alle prime armi con la programmazione in c. Chiedo ai più esperti se è possibile creare un ciclo for in cui l'indice vada prima da 0 a 10, poi da 10 a - 10 e poi dinuovo da - 10 a 0. Grazie in anticipo a chi può aiutarmi.

PM Quote
Avatar
Goblin (Member)
Expert


Messaggi: 375
Iscritto: 02/02/2011

Segnala al moderatore
Postato alle 21:27
Giovedì, 09/04/2020
Invece di un ciclo "for", così senza avere una soluzione scritta, hai pensato ad un while ?
G.


Ibis redibis non morieris in bello
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6075
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 21:30
Giovedì, 09/04/2020
Ma questo ciclo si deve ripetere o deve essere fatto solo una volta?


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti (uno dei padri fondatori del moderno Calcolo delle probabilità) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
nello79 (Normal User)
Newbie


Messaggi: 7
Iscritto: 09/04/2020

Segnala al moderatore
Postato alle 21:48
Giovedì, 09/04/2020
No una sola volta. In che modo il ciclo while?

Ultima modifica effettuata da nello79 il 09/04/2020 alle 21:49
PM Quote
Avatar
Goblin (Member)
Expert


Messaggi: 375
Iscritto: 02/02/2011

Segnala al moderatore
Postato alle 22:11
Giovedì, 09/04/2020
Testo quotato

Postato originariamente da nello79:

No una sola volta. In che modo il ciclo while?  



In C, "al volo" non saprei scriverlo, ci vorrebbe AldoBaldo ... lo butto giù in pascal...

Codice sorgente - presumibilmente Delphi

  1. procedure ciclo;
  2. Var a: Integer;
  3.       b: Boolean;
  4. begin
  5.   a := 0;
  6.   b := True;
  7.   while a<11 do // giro sino a quando a<11
  8.   begin
  9.     Write(a);
  10.     if b then
  11.       inc(a)  // incremento a
  12.     else
  13.       dec(a);  // decremento a
  14.     if (a=10) or (a=-10) then //cambio giro quando sono ai estremi
  15.       b := not b;
  16.     if (a=0) and b then  //quando torna a 0 stoppo tutto
  17.     begin
  18.       write(a);
  19.       break;
  20.     end;
  21.   end;
  22.  
  23. end;



Scritto "al volo" non testato ... ma la logica credo si capisce

G.

Ultima modifica effettuata da Goblin il 09/04/2020 alle 22:12


Ibis redibis non morieris in bello
PM Quote
Avatar
nello79 (Normal User)
Newbie


Messaggi: 7
Iscritto: 09/04/2020

Segnala al moderatore
Postato alle 22:38
Giovedì, 09/04/2020
Potrebbe essere un ' idea.

PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6075
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 0:32
Venerdì, 10/04/2020
Direi che potresti scrivere

Codice sorgente - presumibilmente C/C++

  1. int a, b, s=1;
  2. for (a = b = 0; a <= 40; a++, b += s)
  3. {
  4.         printf("%d ", b);
  5.        
  6.        
  7.         if (b == 10 || b==-10) s = -s;
  8. }


Ultima modifica effettuata da nessuno il 10/04/2020 alle 0:33


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti (uno dei padri fondatori del moderno Calcolo delle probabilità) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
AldoBaldo (Member)
Expert


Messaggi: 544
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 0:50
Venerdì, 10/04/2020
Io ho seguito un ragionamento un po' diverso da quelli proposto dal goblin e da... solo lui, perché non c'è nessun altro. :)

Prima di tutto ho fatto questo, che porta la variabile i a "ciclare" all'infinito tra un limite dato e il suo simmetrico di segno opposto. Per orientare il movimento, viene impostata una variabile dir (per "direzione") che sarà 1 se il limite è positivo, -1 se il limite è negativo. Da notare: questa funzione "gela" il programma, poiché lo "impalla" in una continua ripetizione degli stessi calcoli.

Codice sorgente - presumibilmente C++

  1. void oscilla_ocariddi( int lim ) {
  2.     if( lim )  { // come oscilla intorno allo zero, se e' zero?
  3.         int dir = lim>0 ? 1 : -1; // la direzione punti verso il limite
  4.         int i = 0;
  5.  
  6.         while(1) { // all'infinito
  7.             printf( "%d\n", i );
  8.             i += dir;
  9.  
  10.             if( i==lim ) {
  11.                 dir = -dir; // inverte la direzione dell'incremento
  12.                 lim = -lim; // limite simmetrico rispetto allo zero
  13.             }
  14.         }
  15.     }
  16. }



Come si può notare, la funzione "rifiuta" di impiegare lo zero come parametro, anche perché se i valori devono "oscillare" attorno allo zero, dare limite zero significa impedire l'oscillazione.

In un secondo tempo ho posizionato un valore che agisce da "condizione di fermo" (qZeri, ovvero quantità di zeri), valore che viene incrementato ad ogni "incrocio" di i con lo zero fino a raggiungere una quantità massima determinata dalla quantità delle oscillazioni richieste. Se viene richiesta una sola oscillazione, maxZeri sarà 3, poiché i partirà da zero per raggiungere il limite massimo, quindi invertirà la direzione puntando al simmetrico di segno opposto del limite, attraversando nuovamente lo zero, quindi invertirà ancora una volta la direzione puntando al limite originale ma fermandosi al terzo raggiungimento dello zero. Ogni oscillazione aggiuntiva comporterà due ulteriori incroci con lo zero.

Codice sorgente - presumibilmente C++

  1. void oscilla_ocariddi( int lim, unsigned int qOsc ) {
  2.     if( lim )  { // come oscilla intorno allo zero, se e' zero?
  3.         unsigned int qZeri = 1; // conta la quantita' di incroci con lo zero
  4.         unsigned int maxZeri = qOsc*2+1; // quantita' massima d'incroci con zero
  5.         int dir = lim>0 ? 1 : -1; // la direzione punti verso il limite
  6.         int i = 0;
  7.  
  8.         while( qZeri<=maxZeri ) {
  9.             printf( "%d\n", i );
  10.             qZeri += 0==i;
  11.             i += dir;
  12.  
  13.             if( i==lim ) {
  14.                 dir = -dir; // inverte la direzione dell'incremento
  15.                 lim = -lim; // limite simmetrico rispetto allo zero
  16.             }
  17.         }
  18.     }
  19. }



Volendo si potrebbe anche eliminare la variabile dir, però in quel caso la direzione andrebbe ricalcolata ad ogni ripetizione del ciclo.

Codice sorgente - presumibilmente C++

  1. void oscilla_ocariddi( int lim, unsigned int qOsc ) {
  2.     if( lim )  { // come oscilla intorno allo zero, se e' zero?
  3.         unsigned int qZeri = 1; // conta la quantita' di incroci con lo zero
  4.         unsigned int maxZeri = qOsc*2+1; // quantita' massima d'incroci con zero
  5.         int i = 0;
  6.  
  7.         while( qZeri<=maxZeri ) {
  8.             printf( "%d\n", i );
  9.             qZeri += 0==i;
  10.             lim = (i+=lim>0?1:-1)!=lim?lim:-lim;
  11.         }
  12.     }
  13. }



Ammetto che quest'ultima formulazione l'ho scritta apposta in modo fumoso. :heehee:

P.S. Ho trovato questa definizione di "goblin", ben poco lusinghiera: "...esseri crudeli, barbarici e poco civilizzati, creature spesso fetide e poco apprezzate dalle altre razze. Sebbene in alcuni ambiti siano considerati molto inclini alla creatività e all'ingegno,  cedono volentieri all'impeto e alle passioni, prediligendole quindi ad un raziocinio maggiormente ponderato e alle decisioni sofferte." Non credo tu ti ci riconosca, dai!

Ultima modifica effettuata da AldoBaldo il 10/04/2020 alle 1:06


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
AldoBaldo (Member)
Expert


Messaggi: 544
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 1:41
Venerdì, 10/04/2020
Per distrarmi dalle porcherie che i "vertici" stanno facendo ANCHE nel mondo della scuola, ho voluto strafare. Ecco un programmino che crea pure un grafico della "oscillazione" del valore.

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. void oscilla_ocariddi( int lim, unsigned int qOsc );
  6.  
  7. int main() {
  8.     oscilla_ocariddi( 3, 6 );
  9.     return 0;
  10. }
  11.  
  12. void *crea_array_2d( size_t dim_elem, size_t w, size_t h ) {
  13.     size_t dimRiga = w*dim_elem;
  14.     size_t dimPtr  = sizeof(void*);
  15.  
  16.     void *a2d = calloc( h, dimPtr+dimRiga );
  17.  
  18.     if( a2d ) {
  19.         void *y = a2d;
  20.         void *x = a2d + h*dimPtr;
  21.  
  22.         while( h ) {
  23.             memcpy( y, &x, dimPtr );
  24.             y += dimPtr;
  25.             x += dimRiga;
  26.             --h;
  27.         }
  28.     }
  29.  
  30.     return a2d;
  31. }
  32.  
  33. // attenzione: m non viene verificato!
  34. void mostra_matrice( char **m, size_t qx, size_t qy ) {
  35.     size_t x, y;
  36.  
  37.     for( y=0; y<qy; ++y ) {
  38.         for( x=0; x<qx; ++x ) {
  39.             char c = m[y][x];
  40.             printf( "%c", c?c:' ' );
  41.         }
  42.  
  43.         printf( "\n" );
  44.     }
  45. }
  46.  
  47. void oscilla_ocariddi( int lim, unsigned int qOsc ) {
  48.     if( lim )  { // come oscilla intorno allo zero, se e' zero?
  49.         size_t qx = 4*lim*qOsc+1; // ci sono qx "campioni" nel grafico
  50.         size_t qy = 2*lim+1; // ci sono qy possibili valori per y
  51.         size_t o = lim>0 ? lim : -lim; // o: offset, centra y nel grafico
  52.         unsigned int qZeri = 1; // conta la quantita' di incroci con lo zero
  53.         unsigned int maxZeri = qOsc*2+1; // quantita' massima d'incroci con zero
  54.         size_t x = 0; // x e' per forza positivo
  55.         int y = 0; // y oscilla tra positivo e simmetrico negativo
  56.  
  57.         char **m = crea_array_2d( sizeof(char), qx, qy );
  58.         if( !m ) { puts( "Allocazione fallita" ); return; }
  59.  
  60.         while( qZeri<=maxZeri ) {
  61.             m[o-y][x] = '*';
  62.             qZeri += 0==y;
  63.             lim = (y+=lim>0?1:-1)!=lim?lim:-lim;
  64.             ++x;
  65.         }
  66.  
  67.         mostra_matrice( m, qx, qy );
  68.         free( m ); m = NULL;
  69.     }
  70. }



Ora vado a dormire. Spero di riuscire a reggere il sonno, perché appena smetto di impegnare i neuroni con if, then, else, for, while ecc. mi torna in mente il modo in cui mi (ci) stanno fregando e mi monta la iena in corpo. Magari mi ingollo qualche goccina, va'.
Ciao, programmatori. Dita incrociate.


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Pagine: [ 1 2 3 4 ] Precedente | Prossimo