Newsgroup: it.comp.lang.c
Titolo: liste e passaggio puntatore da funzione a funzione ...a funzione

Se creo una struttura lista così:
--typedef struct nodo
--{int a;
--struct nodo *prox;
--} strutturanodo;
--typedef  strutturanodo *Lista;
e poi la passo ad una funzione tramite puntatore:
--Lista provalista1;
--funz1(&provalista1);
e la funzione è:
--void funz1(Lista *provalista2)
E' tutto corretto ed opero su una unica lista tramite richiamo a puntatori?
Quando esco da funz1 provalista1 è la medesima cosa di ciò che era
provalista2?
Ora se nella funzione funz1 devo chiamare una altra funzione funz2 che deve
operare sempre sulla lista provalista1 dichiarata nel main come gli devo
passare il puntatore?
es:
--void funz1(*provalista2)
--{ funz2(******** );
--};
è la funzione è:
--void  funz2(********** )

 passare il puntatore?
???
Pero':
http://www.google.it/search?q=funzioni+c+passaggio+parametri
http://www.google.it/search?q=puntatori+c
(e pensa che una volta, per imparare, dovevamo per forza andare in 
citta' a comprare i libri... :) )
-- 
Cybertoldo
Per rispondermi via email, sostituisci moc.liamg con 
gmail.com

 citta' a comprare i libri... :) )
Hai imparato abbastanza da riuscire a spiegarlo? Si dice che una cosa la si
conosce veramente solo se si č in grado di farla comprendere ad altri!

 conosce veramente solo se si è in grado di farla comprendere ad altri!
Il punto e' proprio questo. Io non sono riuscito a capire molto dalla 
tua spiegazione del quesito... e ti ho postato i link :-)
PS: non prendere i link a google come offesa: se hai capito bene i 
"puntatori" e il meccanismo del "passaggio parametri a funzione" poi non 
dovresti avere dubbi sul corretto uso.
Ciao


 posta il codice
E' uguale a prima, ti posto un esempio completo e funzionate così è più
chiaro:
Questa è la parte che passa la lista per puntatore:
typedef struct nodo {
 int a;
  struct nodo *prox;
} strutturanodo;
typedef strutturanodo *Lista;
void Funz1(Lista *p2, int n) {
  Lista t1;
  t1=malloc(sizeof(strutturanodo));
  t1->a=n;
  t1->prox=*p2;
  *p2=t1;
}
main()
{
  int num;
  Lista p1;
  p1=NULL;
for (num=0; num<5; num++)
 {
      Funz1(&p1, num);
    }
}
Cosa fa, carica 5 numeri da 0 a 4 dentro ad una lista, come vedi va da main
a funzione (funz1).
Supponiamo adesso di voler passare la lista dal main ad una funzione e
successivamente dalla funzione ad una altra funzione: come si passa la
lista?
void Funz1(Lista *p2, int n) {
  int n1;
  n1= n;
  Funz2( (*&??)p2, n1);
}
void Funz2(Lista (*&???)p3, int n2) {
  Lista t2;
  t2=malloc(sizeof(strutturanodo));
  t2->a=n2;
  t2->prox=(?)p3;
  (?)p3=t2;
}
main()
{
  int num;
  Lista p1;
  p1=NULL;
for (num=0; num<5; num++)
 {
      Funz1(&p1, num);
    }
}
Come vedi la funzione funz1 non fa nulla, passa l'intero come valore, ma la
lista da funz1 a funz2 come la passo? Perchè non ho capito come ripassare ad
una altra funzione (funz2) una precendente lista passata per puntatore(a
funz1).
Se qualcosa non è chiaro sono qui. (Anzi, a me da qui in avanti non è più
chiaro!)

passare il puntatore?
Ti spiego come farei io:
#include <stdio.h>
#include <stdlib.h>
/* dichiaro il tipo node_t */
typedef struct node_tag {
        int data; 
        struct node_tag *next;
} node_t;
/* dichiaro il tipo pnode_t "puntatore a node_t" */
typedef node_t *pnode_t;
/* dichiaro il metodo di creazione di un nodo */
pnode_t node_create(int data) {
        pnode_t i=malloc(sizeof *i);
        if (i) {
           i->next=0;
           i->data=data;    
        }
        return i;
}
/* dichiaro il metodo di aggiunta di un valore a una lista */
void list_add(pnode_t *phead, int data) {
     if (*phead) 
        list_add(&((*phead)->next), data);
     else
       *phead=node_create(data);
}
/* dichiaro il metodo di distruzione di una lista */
void list_destroy(pnode_t head) {
     if (head) {
        list_destroy(head->next);
        free(head);       
     } 
}
/* dichiaro il metodo di output di una lista */
void list_dump(pnode_t head) {
     if (head) {
        printf("%d -> ", head->data, head->next);
        list_dump(head->next);       
     } 
     else printf("NULL\n");
}
int main()
{
    /* dichiaro il puntatore "testa" della lista */
    pnode_t head=0; 
    int i;
 
    /* inserisco n valori random nella lista */
    for (i=0; i<5; i++) 
      list_add(&head, rand()%100);      
 
    /* stampo la lista */  
    list_dump(head);  
    /* dealloco la lista e tutti i suoi elementi */
    list_destroy(head);
 
    return 0;
}
p.s.: mettere il prefisso "--" rende difficile la lettura del codice
che posti.

 che posti.
Infatti, -- perchè erano solo "idee", dopo quando ho riportato
il codice non l'ho messo.

E' una cosa fattibile?
Non ti capisco.  Quello che faccio io passando il puntatore alla testa
della lista da main() a list_add() č *PROPRIO* passare un indirizzo da
una funzione all'altra...

 }
-- 


      *p3=t2;
e qui di nuovo per indirizzo.

 una funzione all'altra...
Ecco, adesso immagina di passare quello che hai passato a list_add()
(proveniente dal main) ad una altra funzione chiamata da dentro a
list_add().
Come glielo passi?
Prova a guardare l'esempio che mi ha scritto Cybertoldo, credo che
Cybertoldo abbia capito cosa intendo ma nemmeno lui č riuscito a trovare una
soluzione.

        printf("%d -> ", head->data, head->next);
Errata Corrige:
 
         printf("%d -> ", head->data);
...č che inizialmente pensavo di stampare anche l'indirizzo di next,
ma poi, tolto il %p dalla format string, non ho aggiornato la lista
dei parametri.

Come glielo passi?
Esattamente come è stato ricevuto:
void f2(pnode_t *p) {
...
}
void f1(pnode_t *p)  {
  f2(p);
}

 mismatch" appunto.
(passaggio per valore...?? dichiarazioni per indirizzo..??)
...rileggi le correzioni e ritenta: errori di sintassi non ne dovrebbe 
dare... almeno quelli :-)
Magari dichiara anche Funz1 dopo Funz2 se non vuoi metterci i prototipi.
ciao


"Andrea Laforgia" <a.laf...@andrealaforgia.it.invalid> ha scritto nel
messaggio news:ha6hg2pehsacknoq8...@4ax.com...

Avresti sbagliato in ogni caso.
Con %p occorre (void *).
E poi "letteralmente" per l'indirizzo di next bisogna
prendere "l'indirizzo": &head->next.
Ma ci vuole sempre (void *).
--
Giorgio Silvestri
DSP/Embedded/Real Time OS   Software Engineer

prendere "l'indirizzo": &head->next.
"L'indirizzo di next" è fraintendibile, effettivamente.
Io intendevo l'indirizzo che il puntatore next contiene, non
l'indirizzo del puntatore next (il cui output servirebbe a ben poco).
Ovviamente, in questo caso, è head->next la scrittura giusta, non
&head->next.

 ha scritto nel messaggio
news:iGSNg.105778$zy5.1...@twister1.libero.it...
Mi pare di aver capito dove sbagliavo.
Mi ero impuntato con cose strane tipo indirizzi di puntatori, &&, &(*...)
invece era molto più semplice!
Grazie a tutti, adesso vi pongo un altro dubbio.