Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Feb 2010
    Messaggi
    25

    [C]raddoppio dei caratteri a mediante liste

    Buongiorno,
    ho fatto un programma che raddoppia il numero delle 'a' presenti nella stringa di 10 caratteri immessa dall'utente. In particolare ho usato le liste.
    Cio' che non capisco è perchè in questa funzione:

    codice:
    void elabora(tp *lista)
    {elem *cursore,*supporto;
    if(*lista!=NULL)
    {if((*(*lista)).c=='a')
    {cursore=malloc(sizeof(elem));
    cursore->c='a';
    cursore->prox=*lista;
    *lista=cursore;
    cursore=NULL;
    supporto=(*(*lista)).prox;
    elabora(&(supporto->prox));}
    else elabora(&((*(*lista)).prox));}}
    se non utilizzo il puntatore supporto e scrivo:

    codice:
    void elabora(tp *lista)
    {elem *cursore;
    if(*lista!=NULL)
    {if((*(*lista)).c=='a')
    {cursore=malloc(sizeof(elem));
    cursore->c='a';
    cursore->prox=*lista;
    *lista=cursore;
    cursore=NULL;
    elabora(&((*(*lista))->prox));}
    else elabora(&((*(*lista)).prox));}}
    il compilatore mi dice che , nella riga sopra evidenziata , l'argomento di elabora è sbagliato...
    a me pero' le due soluzioni sembrano identiche, nel senso che se viene trovata la 'a' riparte la esecuzione della funzione prendendo come parametro attuale :
    codice:
    &((*(*lista))->prox)
    A cosa è dovuto?

    PS La lista è cosi strutturata:
    codice:
    struct elemento{char c;
                      struct elemento *prox;};
    typedef struct elemento elem;
    typedef elem *tp;
    tp lista1;

  2. #2
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    93
    Ciao,

    forse è uguale ma hai provato con:
    codice:
    &(*((*lista)->prox))

  3. #3
    Utente di HTML.it
    Registrato dal
    Feb 2010
    Messaggi
    25
    niente neanche così... in questo modo viene eseguito il programma ma appena digito la stringa l'esecuzione viene terminata 'in modo coatto'

  4. #4
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    93
    puoi postare tutto il codice?

  5. #5
    Utente di HTML.it
    Registrato dal
    Feb 2010
    Messaggi
    25
    Ciao! Ecco il codice completo:
    codice:
    #include <stdio.h>
    
    struct elemento{char c;
                      struct elemento *prox;};
    typedef struct elemento elem;
    typedef elem *tp;
    tp lista1;
    void inizializzazione(tp *lista1);
    void accoda(tp *lista,char el);
    void elabora(tp *lista);
    void stampa(tp *lista);
    
    int main()
    {printf("IL PROGRAMMA RADDOPPIA IL NUMERO DI 'A' PRESENTI NELLA STRINGA DI 10\nCARATTERI IMMESSA DALL'UTENTE\n");
    char string[12];
    char el;
    int i;
    inizializzazione(&lista1);
    printf("Inserire stringa di 10 caratteri: ");
    fgets(string,12,stdin);
    for(i=0;i<10;i++)
    {el=string[i];
    accoda(&lista1,el);}
    elabora(&lista1);
    printf("Risultato:\n");
    stampa(&lista1);
    printf("\n\n");
    system("PAUSE");}
    
    void inizializzazione(tp *lista)
    {*lista=NULL;}
    
    void accoda(tp *lista,char el)
    {elem *cursore;
    if(*lista==NULL)
    {cursore=malloc(sizeof(elem));
    cursore->c=el;
    cursore->prox=NULL;
    *lista=cursore;}
    else accoda(&((*(*lista)).prox),el);}
    
    void elabora(tp *lista)
    {elem *cursore,*supporto;
    if(*lista!=NULL)
    {if((*(*lista)).c=='a')
    {cursore=malloc(sizeof(elem));
    cursore->c='a';
    cursore->prox=*lista;
    *lista=cursore;
    cursore=NULL;
    supporto=(*(*lista)).prox;
    elabora(&(supporto->prox));}
    else elabora(&((*(*lista)).prox));}}
    
    void stampa(tp *lista)
    {if(*lista!=NULL)
    {printf("%c",(*(*lista)).c);
    stampa(&((*(*lista)).prox));}}
    questa qui è la versione con il puntatore supporto, che fa funzionare il programma

  6. #6
    Prova questo
    codice:
    elabora((*lista)->prox);
    Non ho capito perchè nelle funzioni passi un puntatore a tp che è gia puntatore.
    E' una cosa inutile (usato in questo contesto).

    Il programma funziona si, ma è fatto mooolto male (non ti piace indentare il codice ?).
    lolide
    Java Programmer

    Informati

  7. #7
    Utente di HTML.it
    Registrato dal
    Feb 2010
    Messaggi
    25
    Ciao lolide,
    purtroppo la soluzione che mi hai proposto la avevo gia' provata...e anche in questo caso mi lascia inserire la stringa, e quando premo invio appare il messaggio di errore e il programma viene terminato....

    per quanto riguarda il passaggio parametri lo faccio per indirizzo perchè sul mio libro nel capitolo sulle liste fa degli esempi di funzioni per operare con le liste, e effettua i passaggi in questo modo... e cosi ho imparato (piu' o meno ) in questo modo.

    Il programma funziona si, ma è fatto mooolto male (non ti piace indentare il codice ?).
    Lo immagino che sia fatto male visto che sono i primissimi programmi che faccio sulle liste....e poi ho un po' una mente contorta di mio ...cmq non so a me davvero non funziona a meno che, come ho detto, io non metta il puntatore supporto.Per la indentatura la prossima volta provvedero'.

  8. #8
    Utente di HTML.it
    Registrato dal
    Mar 2006
    Messaggi
    93
    Ciao,

    allora, come premessa direi questo:

    In C il passaggio dei parametri alle funzioni è sempre per valore: di ciò che passo viene creata una copia memorizzata in una nuova variabile (quella che poi usiamo nella funzione).

    Se però passiamo l'indirizzo di una variabile e indichiamo come nuova variabile una variabile puntatore cosa succede? L'indirizzo della variabile è copiato nella variabile puntatore. Risultato: possiamo modificare il valore della variabile perché al puntatore che utilizziamo nella funzione è stato assegnato un valore pari all'indirizzo della variabile che abbiamo passato come argomento.

    Per esempio, nel main abbiamo:
    codice:
    int numero=2;
    funzione(&numero);
    invece, come funzione:
    codice:
    funzione(int *x)
    {
       (*x)++;
    }
    Al momento della chiamata il programma prende l'indirizzo di "numero" (supponiamo 1024, numero a caso) e lo copia sullo stack. La variabile x (che è un puntatore) assumerà quindi valore 1024 e, visto che il valore di una variabile puntatore è un'indirizzo di memoria: x punterà a numero e quindi possiamo variare il contenuto di numero utilizzando x.

    Supponiamo ora di avere nel main una variabile puntatore e di voler creare una funzione che allochi memoria e faccia in modo che il puntatore del main punti a questa nuova locazione. Una cosa del tipo:
    codice:
    int *numero=NULL;
    funzione(numero);
    invece, come funzione:
    codice:
    funzione(int *x)
    {
       int *tmp;
       tmp=(int*)malloc(sizeof(int));
       x=tmp;
    }
    non funziona, in quanto: Il programma prende il valore numerico di NULL (indichiamolo sempre con NULL) e lo copia sullo stack. La variabile x conterrà questo valore.
    Quando assegnamo ad x il valore di tmp otteniamo si che x punta alla stessa memoria a cui punta tmp ma non abbiamo cambiato il valore (e quindi l'indirizzo a cui punta) di numero!

    La soluzione? Passare un puntatore ad un puntatore:
    codice:
    int *numero=NULL;
    funzione(&numero);
    invece, come funzione:
    codice:
    funzione(int **x)
    {
       int *tmp;
       tmp=(int*)malloc(sizeof(int));
       *x=tmp;
    }
    Vediamo cosa succede: il programma prende l'indirizzo di numero (che non è NULL, ma un numero in quanto NULL è il contenuto di numero, non il suo indirizzo che supponiamo essere, a caso, 1024) e lo copia sullo stack. La variabile x prende come valore 1024. Essendo un puntatore 1024 sarà visto come indirizzo di qualcosa e, essendo un puntatore ad un puntatore ad un intero, sarà visto come l'indirizzo di un puntatore ad un intero.
    Veniamo a "*x=tmp" vuol dire: il valore puntato da x (quindi il valore contenuto nella locazione 1024 che è il nostro puntatore nel main) dev'essere uguale all'indirizzo puntato da tmp e quindi abbiamo cambiato il valore a cui punta numero!

    Spero solo di essere stato abbastanza chiaro...anche se non ne sono sicuro!

    Ad ogni modo:

    codice:
    struct elemento
    {
      char c;
      struct elemento *prox;
      
    };
    typedef struct elemento elem;
    typedef elem *tp;
    tp lista1;
    void inizializzazione(tp *lista1);
    void accoda(tp *lista,char el);
    void elabora(tp *lista);
    void stampa(tp lista);
    
    int main()
    {
      printf("IL PROGRAMMA RADDOPPIA IL NUMERO DI 'A' PRESENTI NELLA STRINGA DI 10\nCARATTERI IMMESSA DALL'UTENTE\n");
      char string[12];
      char el;
      int i;
      inizializzazione(&lista1);
      printf("Inserire stringa di 10 caratteri: ");
      fgets(string,12,stdin);
      
      for(i=0;i<10;i++)
      {
        el=string[i];
        accoda(&lista1,el);
      }
      elabora(&lista1);
      printf("Risultato:\n");
      stampa(lista1);
      printf("\n\n");
      system("PAUSE");}
      }
    
    void inizializzazione(tp *lista)
    {
      *lista=NULL;
      
    }
    
    void accoda(tp *lista, char el)
    {
      elem *cursore;
    
      if(*lista==NULL)
      {
        cursore=malloc(sizeof(elem));
        cursore->c=el;
        cursore->prox=NULL;
        *lista=cursore;
      }
      else 
        accoda(&(*lista)->prox,el);
    }
    
    void elabora(tp *lista)
    {
      elem *cursore;
    
      if(*lista!=NULL)
      {
        if((*lista)->c=='a')
        {
          cursore=malloc(sizeof(elem));
          cursore->c='a';
          cursore->prox=*lista;
          *lista=cursore;
          //cursore=NULL;
          elabora(&(((*lista)->prox)->prox));
        }
        else 
          elabora(&((*lista)->prox));
       }
      
    }
    
    void stampa(tp lista)
    {
      if(lista!=NULL)
      {
        printf("%c",lista->c);
        stampa(lista->prox);
      }
      
    }

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 © 2025 vBulletin Solutions, Inc. All rights reserved.