Newsgroup: it.comp.lang.c++
Titolo: Aiuto sulle liste.

Salve a tutti, sono alle prime armi con la programmazione in C++, ho un
problema con l'implementazione delle liste. Espongo il quesito:
Devo costruire un overloading dell'operatore di prodotto che, date due
liste, restituisca una nuova lista che č ottenuta concatenando le due liste
date. Ho provato ad implementarla in questo modo ma non so se č giusto:
nodo* operator*(lista lista1,lista lista2)    / /  considerata come funzione
friend
{
if (lista1.head==0) return lista2.head;
else
    nodo*pc=lista1.head;        / / memorizzo il puntatore alla testa della
lista1
    while (pc->link != 0)        / / scorro la lista1
        pc=pc->link;
pc->link=lista2.head;           / / aggancio le due liste
return lista1.head;                / / restituisco l'indirizzo della lista
aggiornata
}
Grazie a tutti coloro che mi potranno aiutare.

date. Ho provato ad implementarla in questo modo ma non so se č giusto:
La libreria standard del linguaggio contiene std::list, non va bene ?

 wrote in message
3ae848ee...@news.libero.it...

No purtroppo la devo scrivere io :( č sbagliata la procedura?

}
Il codice che hai scritto mi sembra funzionare... io faccio pero'
un paio di commenti:
- L'uso di "else" che hai fatto e' molto discutibile: secondo
  me o metti due belle graffe oppure non scrivi "else".
- Non ho capito come e' gestita la proprieta' del nodo... in
  uscita dalla funzione tu restituisci un nodo * (e non un
  oggetto lista) preso dal mezzo da un'altra lista che pero'
  e' temporanea e viene distrutta al momento del return.
  Questo mi fa supporre che il distruttore di lista *non*
  elimini gli elementi (altrimenti il puntatore tornato dalla
  funzione non e' utilizzabile... il nodo a cui punta non
  esiste piu' appena si torna al chiamante).
  Questo significa anche che il costruttore di copia non
  copia anche tutti i nodi (altrimenti si perderebbe memoria
  in continuazione) e implica che se scrivo (a*b) allora
  la lista a viene modificata dall'aver effettuato
  l'operazione (cosa abbastanza diversa dal normale
  comportamento di un operatore di moltiplicazione).
HTH
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

   me o metti due belle graffe oppure non scrivi "else".
La questione è stilistica e, come sempre, solo questione di gusti e
abitudine personale. A me un if else scritto in quel modo risulta
particolarmente gradevole in quanto occupa poco spazio in verticale e
l'indentazione lo rende perfettamente leggibile.
EMG

l'indentazione lo rende perfettamente leggibile.
Hmmm... nulla e' opinabile quanto l'indentazione... ma davvero tu
scrivi cose come...
  if (x)
    return 0;
  else
    y=3;
  foo(y);
???
Lo trovo sorprendente... sarebbe bello avere il tempo di discutere
del perche' "y=3;" e' indentato e "foo(y);" no.
Fra l'altro riguardando il frammento di codice mi accorgo di un
altro problema...
nodo* operator*(lista lista1,lista lista2)
{
  if (lista1.head==0) return lista2.head;
  else
    nodo*pc=lista1.head;
    while (pc->link != 0)
        pc=pc->link;
  pc->link=lista2.head;
  return lista1.head;
}
Quello che compare nel ramo else e' infatti la sola dichiarazione
di pc... che pero' si volatilizza alla riga successiva.
Senza le parentesi graffe (che io metterei comunque per stile
anche se non ci fosse una dichiarazione di variabile) quel
codice e' sintatticamente errato (a meno che esista un simbolo
"pc" globale esterno).


 del perche' "y=3;" e' indentato e "foo(y);" no.
Perché foo(y) non appartiene all'if. Io comunque avrei scritto
if (x)
    return 0;
else
    y=3;
foo(y);
separando con una riga vuota l'if dal resto. Te l'ho detto, lo stile è
una questione personale.
EMG

 una questione personale.
Non capisco con che logica tu dici che y=3 appartiene all'if e foo(y) no.
--
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info 
http://www.brainbench.com/transcript.jsp?pid=2522556

 Non capisco con che logica tu dici che y=3 appartiene all'if e foo(y) no.
Semplicemente perché non ci sono le graffe nel ramo else e quindi ad
esso appartiene una sola istruzione. Oh, ma stiamo scherzando oppure sto
prendendo una clamorosa cantonata?
EMG

 prendendo una clamorosa cantonata?
Il commento a cui tu inizialmente ti sei opposto era che in quel codice sarebbe
meglio omettere l'else oppure racchiudere fra graffe sia y=3 che la chiamata a
foo. E il motivo e' ovviamente non di correttezza ma di leggibilità: messa cosi'
sembra che sia possible eseguire foo senza prima aver assegnato 3 alla y (e
specificatamente nel caso in cui x e' vero). Sembra, non e'. Con quel tipo di
ident la sequenzialità fra l'assegnamento e la chiamata non e' evidente, anche
se e' garantita.


 se e' garantita.
Come l'ho scritto io sopra non c'è alcuna ambiguità (almeno per la mia
abitudine) e foo(y) *non* appartiene all'if. In quest'ultimo caso avrei
scritto
if (x)
    return 0;
else
{
    y=3;
    foo(y);
}
EMG

 }
Io questo lo scriverei addirittura
if ( ! x )
{
    y = 3;
    foo(y);
}
else
    return 0;
Ciao,
Nicola

     return 0;
Hai un motivo preciso per aggiungere un operatore not oppure era solo
uno scherzo? Condivido il resto del messaggio.
EMG


Da un certo punto di vista ho esagerato, perche' l'esempio in se non ha
significato, mentre la mia scelta dipende da cosa effettivamente
esprimono i due rami dell'if. In generale preferisco mettere come primo
ramo il caso "positivo", privo di errori, o in alternativa quello
presumibilmente piu' probabile, e spostare in fondo la gestione degli
errori, piuttosto che i casi eccezionali.
Se c'e' un vantaggio di chiarezza, sono in generale disposto a
"sprecare" ben piu' di una negazione!
Ciao,
Nicola

 "sprecare" ben piu' di una negazione!
Condivido al 100%!
EMG