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.
void oscilla_ocariddi( int lim ) {
if( lim ) { // come oscilla intorno allo zero, se e' zero?
int dir = lim>0 ? 1 : -1; // la direzione punti verso il limite
int i = 0;
while(1) { // all'infinito
printf( "%d\n", i );
i += dir;
if( i==lim ) {
dir = -dir; // inverte la direzione dell'incremento
lim = -lim; // limite simmetrico rispetto allo zero
}
}
}
}
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.
void oscilla_ocariddi( int lim, unsigned int qOsc ) {
if( lim ) { // come oscilla intorno allo zero, se e' zero?
unsigned int qZeri = 1; // conta la quantita' di incroci con lo zero
unsigned int maxZeri = qOsc*2+1; // quantita' massima d'incroci con zero
int dir = lim>0 ? 1 : -1; // la direzione punti verso il limite
int i = 0;
while( qZeri<=maxZeri ) {
printf( "%d\n", i );
qZeri += 0==i;
i += dir;
if( i==lim ) {
dir = -dir; // inverte la direzione dell'incremento
lim = -lim; // limite simmetrico rispetto allo zero
}
}
}
}
Volendo si potrebbe anche eliminare la variabile dir, però in quel caso la direzione andrebbe ricalcolata ad ogni ripetizione del ciclo.
void oscilla_ocariddi( int lim, unsigned int qOsc ) {
if( lim ) { // come oscilla intorno allo zero, se e' zero?
unsigned int qZeri = 1; // conta la quantita' di incroci con lo zero
unsigned int maxZeri = qOsc*2+1; // quantita' massima d'incroci con zero
int i = 0;
while( qZeri<=maxZeri ) {
printf( "%d\n", i );
qZeri += 0==i;
lim = (i+=lim>0?1:-1)!=lim?lim:-lim;
}
}
}
Ammetto che quest'ultima formulazione l'ho scritta apposta in modo fumoso.
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!
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.