Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C] Esercizi "logici" sui puntatori

    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:
    codice:
    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:
    codice:
    #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!

    Grazie in anticipo!

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Quello che non mi e' chiaro e' ... cosa non ti e' chiaro ...

  3. #3
    Svolgo i due esercizi per passi, così capisci

    1)
    codice:
    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!

    codice:
    #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

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Originariamente inviato da Lasentinella
    Svolgo i due esercizi per passi, così capisci
    Ok ...

    codice:
    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 ...)

  5. #5
    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!

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


  6. #6
    Un'ultima difficoltà la ho in questo caso:

    codice:
    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

  7. #7
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    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

  8. #8
    Però quando faccio
    codice:
    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!

  9. #9
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    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

  10. #10
    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!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.