PDA

Visualizza la versione completa : [C] Esercizi "logici" sui puntatori


Lasentinella
24-06-2007, 11:06
Ciao a tutti!
Siccome presto avrò un esame sul C, guardavo i vecchi compiti e ho trovato una tipologia d'esercizio che mi dà qualche problema. Vi scrivo qui sotto due testi di quel tipo, se possibile potreste aiutarmi a capire come si arriva a quei risultati?

1)
Cosa stampa il seguente programma:


main()
{
char *names[]={ "Ron", "Fred", "George",
"Ginny", "Arthur", "Molly"};
char **a, **b, *c;
a=names;
b=a++;
c=*(++b);
printf( "Prima stampa: %s\n", c+2 );
printf( "Seconda stampa: %s\n", c=b[3]+1 );
printf( "Terza stamnpa: %s\n", b[(b-a)+2]);
}


Prima stampa: ed
Seconda stampa: rthur
Terza stamnpa: Ginny

2)Cosa stampa il seguente programma:


#include <stdio.h>
main()
{
char *citta[]={Parigi, Londra, Amsterdam, Torino,
Milano, Roma, Stoccolma};
char **a, *b;
int i=3;
a=&citta[i--];
b=a[1]+i;
printf( Prima stampa: %s\n, b);
printf( Seconda stampa: %s\n, *++a);
b=a[--i]+3;
printf( Terza stampa: %s\n, b );
}


Prima stampa: lano
Seconda stampa: Milano
Terza stampa: a



La cosa che non mi è del tutto chiara è come mai a volte il puntatore (o puntatore di puntatore) punta ad un carattere o all'elemento successivo! :cry:

Grazie in anticipo! :ciauz:

oregon
24-06-2007, 12:39
Quello che non mi e' chiaro e' ... cosa non ti e' chiaro ... :)

Lasentinella
24-06-2007, 12:53
Svolgo i due esercizi per passi, così capisci :D

1)


char *names[]={ "Ron", "Fred", "George",
"Ginny", "Arthur", "Molly"};
char **a, **b, *c;

a=names; //a Punta alla R di RON
b=a++; // B punta alla R di RON, A punta alla O di Ron perché incrementa
c=*(++b); // C punta a RON, b punta alla O di Ron perché incrementa
printf( "Prima stampa: %s\n", c+2 ); //Stampa GEORGE
printf( "Seconda stampa: %s\n", c=b[3]+1 ); //b[3] non esiste
printf( "Terza stamnpa: %s\n", b[(b-a)+2]); //b[2] non esiste
}


Risultato: Non mi viene! :cry:



#include <stdio.h>
main()
{
char *citta[]={Parigi, Londra, Amsterdam, Torino,
Milano, Roma, Stoccolma};
char **a, *b;
int i=3;
a=&citta[i--]; //A punta alla A di Amsterdam, i=2
b=a[1]+i; // B punta alla T di Amsterdam
printf( Prima stampa: %s\n, b); //terdam
printf( Seconda stampa: %s\n, *++a); //boh?
b=a[--i]+3; //boh?
printf( Terza stampa: %s\n, b ); //boh?
}


Come vedi non capisco quando il puntatore di puntatore si sposta all'elemento successivo e quando invece di lettera :confused:

oregon
24-06-2007, 13:08
Originariamente inviato da Lasentinella
Svolgo i due esercizi per passi, così capisci :D

Ok ...



char *names[]={ "Ron", "Fred", "George",
"Ginny", "Arthur", "Molly"};
char **a, **b, *c;

a=names; //a Punta alla R di RON OK
b=a++; // B punta alla R di RON, A punta alla O di Ron perché incrementa
NO ... a e' un puntatore ad un puntatore. Quindi l'operatore ++ fa puntare
a al prossimo puntatore, ovvero a punta alla F di Fred ...
c=*(++b); // C punta a RON, b punta alla O di Ron perché incrementa
NO ... b e' un puntatore a puntatore ... b puntava a RON e ++b punta a FRED
c contiene il puntatore a FRED
printf( "Prima stampa: %s\n", c+2 ); //Stampa GEORGE
NO ... c e' un puntatore a carattere che puntava a FRED
c+2 punta al carattere E di FRED e quindi visualizza ED
printf( "Seconda stampa: %s\n", c=b[3]+1 ); //b[3] non esiste
b[3] esiste, eccome ... b punta a FRED (come b[0])
Quindi b[1] punta a GEORGE, b[2] a GINNY, b[3] ad ARTHUR
b[3]+1 punta al carattere seguente quindi RTHUR
printf( "Terza stamnpa: %s\n", b[(b-a)+2]); //b[2] non esiste
}
b[2] esiste e punta a GINNY (vedi sopra)


L'altro fallo da solo ...

Non hai tenuto presente l'aritmetica dei puntatori.

++ eseguito su un puntatore a carattere, sposta il puntatore al prossimo carattere (ovviamente un +2 lo sposta al carattere successivo ...)

++ eseguito su un puntatore ad un puntatore a carattere, sposta il puntatore al puntatore successivo (nel caso dei nomi, il ++ sposta il puntatore all'inizio del prossimo nome ...)

Lasentinella
24-06-2007, 13:18
Originariamente inviato da oregon

Non hai tenuto presente l'aritmetica dei puntatori.

++ eseguito su un puntatore a carattere, sposta il puntatore al prossimo carattere (ovviamente un +2 lo sposta al carattere successivo ...)

++ eseguito su un puntatore ad un puntatore a carattere, sposta il puntatore al puntatore successivo (nel caso dei nomi, il ++ sposta il puntatore all'inizio del prossimo nome ...)

Praticamente ragionavo esattamente nel modo opposto! :dhò:

Grazie mille dell'aiuto, oggi pomeriggio provo a fare anche gli altri dello stesso tipo e se ho problemi chiedo :)

:ciauz:

Lasentinella
25-06-2007, 12:12
Un'ultima difficoltà la ho in questo caso:



main()
{
int buf[]={ 9, 8, 98, 88, 87, 1, 2, 3, 101, 102, 103, 105 };
int *x[]={buf, buf+4, buf+8};
int *a, **b;

a=x[1]; //a punta a buf+4 ->87 (all'8)
b=x+2; //b punta a buf+8 ->101
printf( "Prima stampa: %d\n", (++a)[2] ); //con ++a dovrebbe puntare a buf+8 ->101, nella
soluzione punta a 3..come interpreto il [2]?
printf( "Seconda stampa: %d e %d\n", **--b, *a);
b-=1;
printf( "Terza stampa: %d\n", *b-a);
}


Soluzione:
Prima stampa: 3
Seconda stampa: 87 e 1
Terza stampa: -5

oregon
25-06-2007, 12:37
Intanto stiamo parlando di valori numerici interi e non di stringhe di caratteri.
Quindi quando scrivi

a=x[1]; // a punta a buf+4 ->87 (all'8)

va bene la prima parte ma non quando scrivi (all'8) ...

Per quanto riguarda il tuo dubbio, considera che a e' un semplice puntatore ad intero.

Se scrivi x+1 allora sposti il puntatore a puntatori (x e' un puntatore doppio) e quindi all'interno del vettore buf, buf+4, buf+8

Ma se scrivi ++a allora ti sposti all'interno del vettore 9, 8, 98, 88, 87, 1, 2, 3, 101, 102, 103, 105 puntando al prossimo valore.

Prima della riga

printf( "Prima stampa: %d\n", (++a)[2] );

a punta al valore 87, quindi ++a punta al prossimo valore dopo l'87, ovvero 1

Dato che valore a cui punta a corrisponde al valore a[0], allora a[2] sara' due valori dopo, ovvero il 3

Lasentinella
25-06-2007, 18:30
Però quando faccio


printf( "Seconda stampa: %d e %d\n", **--b, *a);

b punta a 87; com'è che col b-=1; b punta a 9? Non dovrebbe andare all'elemento precedente dell'array, cioé 88? Eppure mi sembra vada a x=buf!

oregon
25-06-2007, 18:59
b e' un puntatore a puntatore e quindi punta a cio' a cui punta

buf+4

cioe' ad 87 ... ovvero

b -> buf+4 -> 87

Se togli 1 da b vuol dire che lo stai facendo puntare al puntatore precedente, che e' buf, quindi

b -> buf -> 9

Lasentinella
25-06-2007, 22:08
Originariamente inviato da oregon
b e' un puntatore a puntatore e quindi punta a cio' a cui punta

buf+4

cioe' ad 87 ... ovvero

b -> buf+4 -> 87

Se togli 1 da b vuol dire che lo stai facendo puntare al puntatore precedente, che e' buf, quindi

b -> buf -> 9

Chiarissimo!!!! Grazie mille ancora :)

Ciao! :ciauz:

Loading