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);
}
}