|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
Array di struct
Ciao, devo fare questo esercizio, ma il programma mi crasha e non capisco dov'è l'errore, per ora sono alla parte statica.
Codice:
Simulare i C la gestione di 1 pila (stack) tramite array (array di struct) statico e dinamico [che differenza c'è?] Codice:
#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX_SIZE 10 struct pila { char nome[30]; char cognome[30]; int matricola; struct pila *p; } *head; void InserisceTesta(struct pila elenco[], short *n); main() { struct pila elenco[MAX_SIZE]; short what,n_persone=0; head=NULL; while (1) { puts("\nScegli l'operazione:"); puts("[1] Inserisci un elemento in testa"); puts("[2] Esci"); printf("Inserisci Scelta: "); scanf("%hd", &what); switch(what) { case 1: InserisceTesta(elenco,&n_persone); break; case 2: exit(0); break; default: puts("\nScelta sbagliata! Ripeti!\n\n"); } } } void InserisceTesta(struct pila elenco[], short *n) { if (*n==MAX_SIZE) puts("Spazio finito"); else { puts("Scrivi 1 nome"); gets(elenco->nome); puts("Scrivi 1 cognome"); gets(elenco->cognome); puts("Digita la matricola"); scanf("%d", elenco->matricola); head=head->p; head->p=NULL; *n+=1; } } Grazie 1000 per l'aiuto |
![]() |
![]() |
![]() |
#2 | ||
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
La questione è tutta lì, c'è da fare un caso specifico per il primo inserimento. Quote:
- Tramite un array e in questo caso la lista di elementi non serve che sia "linkata" (cioè non c'è bisogno di un puntatore all'elemento seguente). Ci si basa solo su un indice che indica il 'top'. - Tramite una lista linkata e in questo caso è necessario che ogni elemento abbia un puntatore al seguente. In genere in questi casi ogni elemento viene allocato in modo dinamico con malloc ecc...
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
||
![]() |
![]() |
![]() |
#3 |
Junior Member
Iscritto dal: Apr 2007
Messaggi: 9
|
CONCORDO!!
Vorrei inoltre farti notare che una pila è una struttura dati di tipo LIFO (last in- first out), il che significa che gli elementi vengono inseriti sempre in testa. Come hai implementato il codice non penso che l'elemento venga sempre messo in testa. Anzi mi pare che venga sempre aggiunto dopo, e non è il modo corretto per implementarlo!
Inoltre ti do un consiglio: inizializza la struct head nel main, e non in modo globale, perché poi la devi passare alla function di inserimento. Ma adesso cmq riguardando il codice mi sono accorto che c'è un errore di fondo. Tu stai forzando nella funzione di inserimento la creazione di una lista e non un array di struct. Quindi ancora una volta head = head -> p_next deve puntare ad un elemento di un array e non come hai fatto tu. Datti una riguardata al progetto e vedi bene quello che richiede, perché implementato così, a parte che da errore, ma non è neanche ciò che è stato richiesto! La differenza tra statico e dinamico e' la seguente: -statica: array di struct dichiarato in modo statico: array[MIOSIZE] -dinamica: uso di un array dinamico, ovvero si modificano runtime il numero di componenti dell'array con l'uso dell'allocazione dinamica. Ultima modifica di turibbio : 06-06-2007 alle 21:41. |
![]() |
![]() |
![]() |
#4 | |||
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
Innanzitutto grazie per le risposte
![]() Quote:
Quote:
Quote:
![]() |
|||
![]() |
![]() |
![]() |
#5 |
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
Ho modificato cosi', mi da lo stesso problema di prima: non mi fa leggere il nome, ma solo cognome e matricola (tra l'altro è una lettura fittizia perchè nelle stampe mi da caratteri a casaccio).
Codice:
#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX_SIZE 10 struct pila { char nome[30]; char cognome[30]; int matricola; }; void InserisceTesta(struct pila elenco[], short *n); void Elimina_pila(struct pila elenco[],short *n); void CancellaTesta(struct pila elenco[],short *n); void StampaTesta(struct pila elenco[], short *n); void StampaPila(struct pila elenco[], short *n); main() { struct pila elenco[MAX_SIZE]; short what,n_persone=0; while (1) { puts("\nScegli l'operazione:"); puts("[1] Inserisci un elemento in testa"); puts("[2] Cancella Pila"); puts("[3] Stampa numero elementi nella pila"); puts("[4] Elimina elemento in testa"); puts("[5] Stampa testa"); puts("[6] Stampa pila"); puts("[7] Esci"); printf("Inserisci Scelta: "); scanf("%hd", &what); switch(what) { case 1: InserisceTesta(elenco,&n_persone); break; case 2: Elimina_pila(elenco,&n_persone); break; case 3: if (n_persone!=1) printf("\nCi sono %d elementi nella pila\n",n_persone); else puts("\nC'è 1 elemento nella pila"); break; case 4: CancellaTesta(elenco,&n_persone); break; case 5: StampaTesta(elenco,&n_persone); break; case 6: StampaPila(elenco,&n_persone); break; case 7: exit(0); break; default: puts("\nScelta sbagliata! Ripeti!\n\n"); } } } void InserisceTesta(struct pila elenco[], short *n) { short i=(*n)-1; if (*n==MAX_SIZE) puts("Spazio finito"); else { puts("Scrivi 1 nome"); gets(elenco[i].nome); puts("Scrivi 1 cognome"); gets(elenco[i].cognome); puts("Digita la matricola"); scanf("%d", elenco[i].matricola); *n+=1; } } void Elimina_pila(struct pila elenco[],short *n) { short i; if (n==NULL) puts("La pila non contiene nodi"); else { for (i=0;i<(*n);i++) { elenco[i].nome==NULL; elenco[i].cognome==NULL; elenco[i].matricola=0; } } *n=0; } void CancellaTesta(struct pila elenco[],short *n) { short i=(*n)-1; if (n==NULL) puts("La pila non contiene nodi"); else { elenco[i].nome==NULL; elenco[i].cognome==NULL; elenco[i].matricola=0; } *n=i; } void StampaTesta(struct pila elenco[], short *n) { short i=(*n)-1; if (i>=0) printf("\nStudente %s %s, matr. %d",elenco[i].nome, elenco[i].cognome, elenco[i].matricola); else puts("\nNon ci sono persone nella pila"); } void StampaPila(struct pila elenco[], short *n) { short i; if (n=NULL) puts("La pila non conviene nodi"); else { for (i=0;i<(*n);i++) printf("Studente %s %s, matr. %d",elenco[i].nome, elenco[i].cognome, elenco[i].matricola); } } |
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Se mi permetti, ti consiglio di gestire la pila in modo un pochino diverso:
Codice:
struct elem_pila { char nome[30]; char cognome[30]; int matricola; }; struct pila { struct elem_pila elementi[MAX_SIZE]; int size; }; ![]()
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
![]() |
![]() |
![]() |
#7 |
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
Ho fatto come mi hai detto, pero' ho sbagliato qualcosa, ora crasha addirittura il prog alla prima lettura
Codice:
#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX_SIZE 10 struct elem_pila { char nome[30]; char cognome[30]; int matricola; }; struct pila { struct elem_pila elenco[MAX_SIZE]; int n; }stack; void InserisceTesta(); void Elimina_pila(); void Lunghezza(); void CancellaTesta(); void StampaTesta(); void StampaPila(); main() { short what; while (1) { puts("\nScegli l'operazione:"); puts("[1] Inserisci un elemento in testa"); puts("[2] Cancella Pila"); puts("[3] Stampa numero elementi nella pila"); puts("[4] Elimina elemento in testa"); puts("[5] Stampa testa"); puts("[6] Stampa pila"); puts("[7] Esci"); printf("Inserisci Scelta: "); scanf("%hd", &what); switch(what) { case 1: InserisceTesta(); break; case 2: Elimina_pila(); break; case 3: Lunghezza(); break; case 4: CancellaTesta(); break; case 5: StampaTesta(); break; case 6: StampaPila(); break; case 7: exit(0); break; default: puts("\nScelta sbagliata! Ripeti!\n\n"); } } } void InserisceTesta() { short i=(stack.n)-1; if (stack.n==MAX_SIZE) puts("Spazio finito"); else { puts("Scrivi 1 nome"); gets(stack.elenco[i].nome); puts("Scrivi 1 cognome"); gets(stack.elenco[i].cognome); puts("Digita la matricola"); scanf("%d", stack.elenco[i].matricola); stack.n+=1; } } void Elimina_pila() { short i; if (&stack.n==NULL) puts("\nLa pila non contiene nodi"); else { for (i=0;i<(stack.n);i++) { stack.elenco[i].nome==NULL; stack.elenco[i].cognome==NULL; stack.elenco[i].matricola=0; } } stack.n=0; } void CancellaTesta() { short i=(stack.n)-1; if (&stack.n==NULL) puts("\nLa pila non contiene nodi"); else { stack.elenco[i].nome==NULL; stack.elenco[i].cognome==NULL; stack.elenco[i].matricola=0; } stack.n=i; } void StampaTesta() { short i=(stack.n)-1; if (i>=0) printf("\nStudente %s %s, matr. %d",stack.elenco[i].nome, stack.elenco[i].cognome, stack.elenco[i].matricola); else puts("\nNon ci sono persone nella pila"); } void Lunghezza() { if (stack.n!=1) printf("\nCi sono %d elementi nella pila\n",stack.n); else puts("\nC'è 1 elemento nella pila"); } void StampaPila() { short i; if (&stack.n==NULL) puts("La pila non conviene nodi"); else printf("Studente %s %s, matr. %d\n",stack.elenco[i].nome, stack.elenco[i].cognome, stack.elenco[i].matricola); { for (i=0;i<(stack.n);i++) printf("Studente %s %s, matr. %d\n",stack.elenco[i].nome, stack.elenco[i].cognome, stack.elenco[i].matricola); } } |
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
In InserisceTesta fai short i=(stack.n)-1;, all'inizio quindi i è -1 ...... vai un po' fuori dall'array! Poi perché in StampaPila fai if (&stack.n==NULL)?? L'indirizzo di stack.n non può essere NULL! Credo che debba rivedere bene un po' tutta la gestione della pila.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Sep 2005
Città: Opinions are like assholes: anybody has one...
Messaggi: 34290
|
e metti un controllino sul what (tipo un isnum)
lo switch non accetta altro che interi
__________________
Ну давай !! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Cina, bugiardo - stolen conto: non paghi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . NON CERCO PIU' UN ALIMENTATORE DECENTE ----------------> LINK |
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Secondo lo standard ANSI C, l'espressione nello switch può essere di tipo char, short, int o long
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
![]() |
![]() |
![]() |
#11 | ||||
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
Quote:
Quote:
Quote:
Sono troppo poco esperto, mi serve il vostro aiuto ![]() Quote:
Ultima modifica di k_mishima : 07-06-2007 alle 17:05. Motivo: errori di scrittura |
||||
![]() |
![]() |
![]() |
#12 | |
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Quindi puoi fare stack.n == 0
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
![]() |
![]() |
![]() |
#13 | |
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
Quote:
Per il crash non sai dirmi che ho sbagliato? |
|
![]() |
![]() |
![]() |
#14 |
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
up
|
![]() |
![]() |
![]() |
#15 | ||
Junior Member
Iscritto dal: Apr 2007
Messaggi: 9
|
Quote:
Dovresti implementare la stack utilizzando qualcosa di questo tipo: Quote:
info pila[MAXSIZE]; Il controllo degli elementi massimi li fai con una variabile int cnt, che utilizzi incrementandola (push) e decrementadola (pop); Puoi magari utilizzare cnt per mantenere la posizione dove inserire il prossimo elemento, posizionando così gli elementi nell'array in maniera sequenziale. |
||
![]() |
![]() |
![]() |
#16 |
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
io cosi' avevo fatto, poi ho cambiato su consiglio di andbin per fare il codice piu' elengante e evitare di passare ogni volta le stesse cose alle function, cmq guarda, mi è indifferente, vorrei piuttosto sapere perchè mi crasha sto cavolo di prog
![]() |
![]() |
![]() |
![]() |
#17 | ||||||
Junior Member
Iscritto dal: Apr 2007
Messaggi: 9
|
Ho provato il tuo codice e ti posso dire che ci sono un casino di errori e di incongruenze. Innanzitutto riprendendo il codice originale una cosa del tipo:
Quote:
Se il tuo obiettivo è di inizializzare l'elemento a zero lo puoi fare in questo modo: Quote:
Nella funzione di inserimento ci sono due errori importanti: Quote:
fflush(stdin); per pulire lo standard di input a cui è associato il programma, altrimenti la gets ti prende valori di tabulazione come il newline che non dovrebbe ricevere. Quote:
Quote:
pertanto lo risolvi in questo modo: Quote:
|
||||||
![]() |
![]() |
![]() |
#18 |
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
grazie 1000, pian piano stavo scoprendo tutti questi errori, mi mancava solo quello sulla scanf (&) che mi faceva ancora crashare
![]() ammetto di essermela dimenticata ![]() purtroppo il programma non mi dava errore ![]() oggi lo faccio dinamicamente allora, se ho problemi posto ![]() |
![]() |
![]() |
![]() |
#19 |
Junior Member
Iscritto dal: Apr 2007
Messaggi: 9
|
Si infatti non ti segnala né errori né warnign in base al fatto che i compilatori non sono previsti per segnalarlo. In realtà è lo standard del C stesso che non dice nulla al riguardo. Pertanto è compito del programmatore fare attenzione a passare un indirizzo.
Quando fai la versione dinamica abbi presente che l'array deve essere di tipo dinamico e pertanto devi aumentare o diminuire il suo size a seconda dell'inserimento o dell'eliminazione. ![]() |
![]() |
![]() |
![]() |
#20 |
Member
Iscritto dal: Jan 2007
Messaggi: 173
|
ecco, sono già nei guai. Voglio allocare dinamicamente la struct, ma come si fa?
Per ora ho scritto Codice:
struct elem_pila { char nome[30]; char cognome[30]; int matricola; }*elenco; Codice:
elenco=(struct elem_pila*)calloc((1,sizeof(struct elem_pila)); |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 10:01.