PDA

Visualizza la versione completa : programma con puntatori [C]


glukosio
15-01-2013, 17:23
ciao a tutti, ho il libro di Deitel&Deitel sul C, e fra gli esercizi per i puntatori c'è questo esercizio qui:
http://books.google.it/books?id=Jz9zhsQJ_8AC&lpg=PA536&hl=it&pg=PA292#v=onepage&q&f=false (a pagina 292)

ho scritto il programma ma non so però come farlo con i puntatori, cioè non so come potrebbero essere utilizzati in questo contesto... questo è il codice che ho scritto:


#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void){
char tartaruga[70]={0};
char lepre[70]={0};
int curT=0;
int curL=0;
int T=0,L=0;
int count;
srand(time(NULL));

for(curT=0,curL=0;curT<=69||curL<=69;){
T=1+(rand()%10);
L=1+(rand()%10);
//mosse tartaruga
if(T>=1&&T<=5){
tartaruga[curT]=0;
tartaruga[curT+3]='T';
curT+=3;
}
if(T>=6&&T<=7){
if(curT-6>=0){
tartaruga[curT]=0;
tartaruga[curT-6]='T';
curT-=6;
}
else{
tartaruga[curT]=0;
tartaruga[0]='T';
curT=0;
}
}
if(T>=8&&T<=10){
tartaruga[curT]=0;
tartaruga[curT+1]='T';
curT+=1;
}
//mosse lepre
if(L>=1&&L<=2){
continue;
}
if(L>=3&&L<=4){
lepre[curL]=0;
lepre[curL+9]='L';
curL+=9;
}
if(L==5){
if(curL-12>=0){
lepre[curL]=0;
lepre[curL-12]='L';
curL-=12;
}
else{
lepre[curL]=0;
lepre[0]='L';
curL=0;
}
}
if(L>=6&&L<=8){
lepre[curL]=0;
lepre[curL+1]='L';
curL+=1;
}
if(L>=9&&L<=10){
if(curL-2>=0){
lepre[curL]=0;
lepre[curL-2]='L';
curL-=2;
}
else{
lepre[curL]=0;
lepre[0]='L';
curL=0;
}
}
if(curT<0) curT=0;
if(curL<0) curL=0;
for(count=0;count<70;count++){
printf("%c",tartaruga[count]);
}
printf("\n");
for(count=0;count<70;count++){
printf("%c",lepre[count]);
}
if(curT>=69||curL>=69) break;
else {
sleep(1);
system("cls");

}
}
if(curT>=69){
printf("\nHa vinto la tartaruga!\n");
}
if(curL>=69){
printf("\nHa vinto la lepre!\n");
}
return 0;
}

qualche consiglio su come sfruttare i puntatori? :D

oregon
15-01-2013, 18:01
E' una domanda troppo generica ... i puntatori puoi utilizzarli ovunque, ma anche a sproposito, non è detto che servano sempre e comunque.

In ogni caso, prova ad allocare dinamicamente (con la malloc) i due vettori, utilizzando due vettori

char *tartaruga;
char *lepre;

e vedrai i cambiamenti nel programma.

glukosio
15-01-2013, 18:36
ti ringrazio della risposta, ma non ho ancora studiato malloc e non volevo discostarmi troppo dal libro, quindi passo questo esercizio e forse ci ritornerò più avanti ;)

MdE2005
15-01-2013, 19:33
Al di là dell'utilizzo dei puntatori, vorrei farti notare alcune incongruenze, se me lo permetti.

La variabile T l'hai dichiarata come int, quindi un intero; per tale motivo nella successione dei numeri stessi il numero 7 si trova dopo il 6, così come tra l'8 e il 10 c'è solo il 9 come numero intero, come saprai.
Per questo motivo queste righe di codice non hanno molto senso:

if(T>=6&&T<=7ù)
if (T>=8&&T<=10) --> quindi if (T=9)

Diverso è il caso se invece usavi un tipo diverso di dato.

Ciao :)

glukosio
15-01-2013, 19:46
l'operatore usato è un "maggiore e uguale" e un "minore e uguale", quindi i numeri 8 e 10 qui:

if (T>=8&&T<=10) sono compresi... se non sbaglio sono 8,9,10 i numeri che soddisfano tali limiti, per l'altro if, il ragionamento è lo stesso e include sia 6 sia 7.

più avanti nel codice ho usato
if(L==5), proprio perchè è solamente quel valore li.
comunque se avete delle osservazioni di qualunque genere da fare sono ben accette, sono ancora alle prime armi e vorrei puntare sempre più in alto, i consigli non mi dispiacciono ;)

MdE2005
15-01-2013, 20:29
Sì, in effetti non avevo fatto caso al segno '"=". In ogni caso tra 6 e 7 sarebbe stato più semplice usare un OR, in quanto è più leggibile e semplifica la lettura e l'intepretazione.

Ciao :)

glukosio
15-01-2013, 20:38
si hai ragione grazie ;)
ciao! :D

franzauker2.0
15-01-2013, 22:00
Al netto delle osservazioni sbagliate puoi adottare tutta una serie di "automatismi" mentali i quali possono, anche no, essere utili.
Mi riferisco a certi "rischi" che sono insiti nel funzionamento dei compilatori e del relativo standard che possono essere diversi tra i vari paradigmi.
Facciamo un paio di esemi.
L'utilizzo delle parentesi per rendere esplicito (ed univoco) la priorità degli operatori.
Non è detto che la gerarchia di un certo linguaggio sia la medesima per gli altri; disambiguare - anche quando non strettamente necessario - è generalmente cosa buona e giusta.
Analoga applicazione sugli OR, e quindi sulla valutazione completa delle espressioni oppure no.
Espressioni del genere a OR b sono, in generale, abbastanza "rischiose", non tanto per un linguaggio preciso (puoi riferirti allo standard per sincerarti di come vengono valutate queste espressioni), quanto piuttosto acquisire un "automatismo" che, magari domani, quando lo "porterai" in un altro ambiente, potrebbe dare risultati diversi da quelli che ti aspetti.

Riguardo al sorgente le "prime" cose da fare, come correttamente sopra segnalato, è svincolarsi dalla dimensione precisa del problema, ad esempio dalla cardinalità del vettore che utilizzi.
Potrebbe essere cosa buona e giusta dichiarare unsigned le variabili che non lo sono, non perchè ciò sia indispensabile, ma "giusto per".

Altro elemento da valutare con grande cura, quando si opera in maniera "bruta" su vettori C "lisci", è quella di limiti delle variabili (o espressioni) indice.
Ovviamente il modo "giusto" o comunque "più furbo" è utilizzare funzioni, di libreria o scritte ad hoc, che si facciano carico di queste operazioni potenzialmente pericolose.
Questo ad esempio

tartaruga[curT-6] è un po' a rischio, nel senso che v'è un assunto "nascosto" sull'intervallo di curT.
Potresti adottare una strategia non dico "simil-oggetti", ma astrarti un minimo dalla gestione dei vettori può essere indicato, anche senza supercomplicazioni.

Poi, sempre nell'ottica diciamo così "cosmetica", il doppio ciclo lo eviterei, a favore di un doppio ciclo esplicito.
Perchè? Perchè in altri paradigmi il costrutto semplicemente non esiste (si riapplica il ragionamento precedente) e, in questo caso, non fornisce un vantaggio tale per cui abbia un suo "senso" particolare.

Mettiamoci poi dentro che, come prassi, break-are un ciclo iterativo non è esattamente chiarissimo, o meglio tipicamente si presume (sempre dal punto di vista della logica, non dell'obbligo) che un ciclo for sia già ben definito nelle sue iteriazioni (questo consente - per inciso - una eventuale ottimizzazione a "srotolamento", cosa non molto comune, ma da tenere presente -), mentre il while (e cugini) sono usualmente più chiari nello specificare che esiste una "qualche condizione" di uscita

Riguardo poi alla denominazione della variabili esistono le stesse scuole di pensiero utilizzate per la rottura delle uova dal lato corto o lungo, con guerre di ferocia pari a quelle del famoso racconto.

Personalmente suggerisco (retaggio FORTRAN) di usare variabili per i cicli iterativi "standard" con singolo carattere, i,j,k.
E', storicamente, più facile aspettarsi che for (i=0...) implichi un vero iteratore, piuttosto che for(contatore=...), quindi variabili con nome a singolo carattere dovrebbero rappresentare valori "volatili" (stringhe temporanee e così via).

Le variabili poi, in un mondo ideale, sono bilanciate tra lunghezza (=tempo che ci vuole a scrivere) e chiarezza.
Tra c_arrayConElencoDelleMosseFatteDallaLepre qualcosa di più sintetico ma meno chiaro un certo equilibrio è auspicabile.

Sono comunque suggerimenti, non articoli di fede.

glukosio
16-01-2013, 14:58
ok grazie mille dei consigli, provvederò a sfruttarli :)

Loading