|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: May 2001
Città: Monza
Messaggi: 4054
|
Mi aiutate con queste cosine in C ??[HELP INSIDE]
Ciao,
devo fare l'esame di info di ingegneria che mi porto ormai dietro da anni..... Ho capito tutto fino ad ora.....appunto fino ad ora. Potete cercare di farmi capire come si usano le liste e l'allocazione dinamica della memoria malloc e il suo amico free ?? Sto cercando di fare il seguente programma: Si implementino le strutture dati CANZONE e NODO e le opportune procedure per realizzare una lista di brani musicali. In particolare di ogni brano dovrà essere memorizzato il titolo,l?autore e la durata (in secondi). L?applicazione dovrà permettere le seguenti operazioni (realizzate tramite opportune funzioni):?inserimento di un brano in coda alla lista?rimozione del brano in cima alla lista?ricerca di un brano?inserimento di un brano (in una posizione qualsiasi)?rimozione di un brano (in una posizione qualsiasi) BRANCOLO NEL BUIO PIU TOTALE !
__________________
Dostoevskij "La bellezza salverà il mondo" Ultima modifica di luckye : 18-01-2004 alle 12:07. |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Codice:
struct canzone {
char *titolo;
char *autore;
int durata;
};
struct nodo {
struct canzone;
struct nodo *next;
};
/*Per allocare una nuova canzone*/
struct canzone *alloca(char *titolo, char *autore, int durata)
{
struct canzone *tmp;
tmp = (canzone *)malloc(sizeof(canzone));
tmp->titolo = (char *)malloc(sizeof(char)*(strlen(titolo)+1));
tmp->autore = (char *)malloc(sizeof(char)*(strlen(autore)+1));
strcpy(tmp->titolo, titolo);
strcpy(tmp->autore, autore);
tmp->durata = durata;
return tmp;
}
/*Per deallocare una canzone - gli passo il puntatore al puntatore
per rendere NULL il puntatore anche nella funzione chiamante*/
void alloca(struct canzone **c)
{
free((*c)->titolo);
free((*c)->autore)
free(*c);
(*c) = NULL;
}
/*utilizzo*/
struct canzone *c;
c = alloca("Seek'n Destroy", "Metallica", 280);
....
....
....
dealloca(&c);
|
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: May 2001
Città: Monza
Messaggi: 4054
|
Ma non bisogna controllare che la lista non sia vuota ?? se faccio un puntatore a Null si verifica un errore no ?
__________________
Dostoevskij "La bellezza salverà il mondo" |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
In quello che ho scritto sopra non ho trattato niente della lista (a parte la struttura)...
Per la lista funziona come qualsiasi altra lista |
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: May 2001
Città: Monza
Messaggi: 4054
|
Quote:
__________________
Dostoevskij "La bellezza salverà il mondo" |
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Le liste sono tutte uguali
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
cosa fa la malloc, e quindi a cosa serve? la funzione malloc ha il seguente prototipo
void * malloc (size_t size); la funzione malloc serve a creare (o per meglio dire, riservare per l'utilizzo del programma) spazio in memoria grande quanto l'intero size (size_t consideralo come il tipo intero), e ti restituisce il puntatore alla prima cella di questa memoria che hai riservato. per esempio se voglio riservare uno spazio in memoria dove poi andrò a mettere un intero devo chiamare la malloc scrivendo malloc (<spazio occupato da un intero in memoria>); poichè un programmatore non è tenuto a sapere quanto spazio in memoria occupa un intero (credo che occupi 2 byte) e anche perchè questo valore cambia in base all'architettura della macchina allora si usa quasi sempre la sizeof che è una funzione che restituisce lo spazio che occupa un certo dato o un certo tipo di dato. quindi ti consiglio di usare la malloc in questo modo: - abbiamo detto che malloc restituisce un puntatore, quindi all'interno del programma dichiaro un puntatore (in questo esempio creo un puntatore ad intero); Codice:
. . . int *p; p= (int *) malloc (sizeof(int)); . . Codice:
p= (int *) malloc ( 15 * sizeof(int)); la funzione free diciamo che è l'inverso della malloc: libera spazio in memoria. supponiamo che ora io debba cancellare lo spazio in memoria che prima ho allocato e che era puntato da p. il prototipo della funzione free è il seguente: void free (void *ptr) cioè tu devi passare a free il puntatore all'area di memoria che vuoi disallocare (si dice così?? Codice:
. . free(p); . ora passiamo alle liste beh lo dice la parola stessa, una lista è una lista (sequenza) di elementi. posso benissimo creare una lista di interi, ma di solito una lista si usa per gestire ADT (tipi di dato astratti) più complicati. per descrivere, cioè per far capire al compilatore, com'è fatto un elemento della lista (cioè quali sono le cose che caratterizzano il singolo elemento), usare una struttura è il modo più semplice e intuitivo (nonchè l'unico che io conosca Codice:
struct song {
char autore[25];
char titolo[25];
int durata;
};
typedef struct song itemtype;
Codice:
typedef struct list *ptr;
typedef struct list {
itemtype item;
ptr next;
};
A questo punto ho solo descritto la lista, ma non ho ancora descritto alcuna funzione per inserire, togliere ecc. insomma per gestire queste lista. Ti posso scrivere qui di seguito degli esempi di funzioni che potresti utilizzare per gestire la lista. Devi innanzitutti ricordarti di creare (nel main) la lista semplicemente creando il puntatore al primo elemento con la malloc: Codice:
ptr lista1; lista1= (struct list *) malloc (sizeof(struct list)); Codice:
void init_list (ptr lista) {
*lista=NULL;
}
Ora la funzione che ti inserisce un elemento in ultima posizione (in coda alla lista): Codice:
void insert_last (ptr lista, itemtype i) {
ptr tmp;
tmp=lista;
while (*tmp!=NULL) tmp=tmp->next;
tmp->item=i;
}
Rimozione del brano in cima alla lista (semplicemente scorro il puntatore di 1 posizione) Codice:
void delete_first (ptr lista) {
lista=lista->next;
}
Ora la funzione di ricerca di un brano. Chiaramente restituirà il puntatore all'elemento, in caso positivo, e restituirà NULL altrimenti: Codice:
ptr search (ptr lista, char *aut, char *nome, int lung) {
ptr tmp;
tmp=lista;
while (strcmp(aut, tmp->autore) && strcmp(nome, tmp->titolo) && tmp->durata!=lung) {
tmp=tmp->next;
if (tmp==NULL) return NULL;
}
return tmp;
}
Per quanto riguarda l'inserimento e la rimozione in una posizione qualsiasi ti prego di essere più chiaro perchè non ho capito esattamente cosa vuoi fare. Spero che ti sia stato d'aiuto, se hai dubbi facci sapere. ciao! Ultima modifica di VegetaSSJ5 : 18-01-2004 alle 16:08. |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: May 2001
Città: Monza
Messaggi: 4054
|
chiarissimo....... grazie mille. Ora cerco di capire meglio la traccia dell'esercizio e ti rispiego cosa devo fare.
Vsito che sei online..... questo programma deve semplicemente calcolare il numero dei divisori........ #include <stdio.h> int calcoladivisore(int n){ int cont,temp; temp=n; cont=0; while(temp!=0) {if((n/temp)%2==0||temp==n) {cont++; temp--; } else temp--; } return cont; } void main() { int numero,divisori; numero=1; printf("Inserire un numero: "); scanf("%d",&numero); divisori=calcoladivisore(numero); printf("Il numero dei divisori e %d",divisori); } Mi sai dire prechè se metto 8,temp scende fino a 0 a passi di uno.....e quando (8/temp )%2==0 con temp=3 incrementa il contatore come se 8/3 abbia resto zero ???
__________________
Dostoevskij "La bellezza salverà il mondo" |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: May 2001
Città: Monza
Messaggi: 4054
|
__________________
Dostoevskij "La bellezza salverà il mondo" |
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
Quote:
|
|
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: May 2001
Città: Monza
Messaggi: 4054
|
Quote:
__________________
Dostoevskij "La bellezza salverà il mondo" |
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
ho riscritto il programma, questo sembra funzionare correttamente (ho fatto solo 2 prove quindi non ve lo assicuro!!!
Codice:
include <stdio.h>
int calcoladivisore (int n) {
int cont=0, i=0;
if (n==0) return -1;
for (i=1; i<=n; ++i) if (!(n%i)) ++cont;
return cont;
}
void main() {
int numero=0, divisori=0;
printf("Inserire un numero: ");
scanf("%d",&numero);
divisori=calcoladivisore(numero);
printf("Il numero dei divisori e %d\n",divisori);
system ("PAUSE");
}
Ultima modifica di VegetaSSJ5 : 18-01-2004 alle 16:25. |
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: May 2001
Città: Monza
Messaggi: 4054
|
ma vorrei capire xè il mio non funzionava......
__________________
Dostoevskij "La bellezza salverà il mondo" |
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
l'errore secondo me era qui
Codice:
if((n/temp)%2==0||temp==n) Codice:
if (!(n%i)) ++cont; |
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Apr 2002
Città: Vigevano(PV)
Messaggi: 2124
|
include <stdio.h>
int div = 0; // il num dei divis int cnt; int calcoladivisore (int n, int * div, int * cnt) { if (n==0) return -1; ++div; ++cnt return calcoladivisore(n % cnt); } void main() { printf("Inserire un numero: "); scanf("%d",&numero); calcoladivisore(numero); printf("Il numero dei divisori e %d\n",cnt); system ("PAUSE"); }
__________________
Gnu/Linux User
|
|
|
|
|
|
#16 | |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
Quote:
|
|
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: May 2001
Città: Monza
Messaggi: 4054
|
Quote:
Il programma stupidissimo cioè questo dei divisori,l'avevo fatto per provare una cosa.......fatto sta che non funzionava e estratto il pezzo di codice sopra mi ero reso conto di quel problema. Ora spiegami...... ma quando dichiaro una lista.....il c sa già che è tale ? non riesco a capire il suo funzionamento.Mi sembra una struct.......con quel *next che boh.....non capisco...... cioè prima l'inizializzo come variabile globale a null giusto ?? dopodiche devo ricordarmi di creare un'inizio e una fine..... non mi è chiara.........
__________________
Dostoevskij "La bellezza salverà il mondo" |
|
|
|
|
|
|
#18 | |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
Quote:
cosa intendi per "ma quando dichiaro una lista... il c sa già che è tale?" allora ti ripeto brevemente il concetto. tu hai creato la struttura song, e questo è il tuo (io lo chiamo così) itemtype, cioè il "tipo" che caratterizza il singolo elemento della lista. tuttavia devi ricordare che per creare una lista c'è bisogno di specificare SIA l'itemtype, ovvero la struttura song, SIA il puntatore all'elemento successivo, e cioè ptr *next. Se tu non hai questo puntatore, come faresti ad accedere all'elemento successivo della lista? Questa è la caratteristica principale della lista. Invece di essere una struttura dati indicizzata (che si scorre tramite indice, come un array), la lista si scorre tramite i puntatori agli elementi successivi. Poi ci sono altre strutture dati simili come le code, gli alberi ecc. che possono avere anche più di un puntatore, ad es. la coda ha un puntatore alla testa e un puntatore alla coda. Spero di essere stato chiaro. Riassumo: Codice:
struct song {
char autore[25];
char titolo[25];
int durata;
};
typedef struct song itemtype;
typedef struct list *ptr;
typedef struct list {
itemtype item;
ptr next;
};
Ultima modifica di VegetaSSJ5 : 19-01-2004 alle 10:12. |
|
|
|
|
|
|
#19 | |
|
Senior Member
Iscritto dal: Sep 2002
Città: Celano (AQ) Segno_Zodiacale: Leone Ascendente: Cammello Segni_Particolari: Quello
Messaggi: 9571
|
Quote:
allora tu nel main del programma per creare una lista ti devi creare il puntatore all'inizio della lista (come ti ho detto la lista non ha il puntatore alla fine della lista, però questa è una caratteristica che volendo ci si può aggiungere tranquillamente). per creare questo puntatore all'inizio della lista fai così: Codice:
ptr lista1; lista1= (struct list *) malloc (sizeof(struct list)); una volta creato il puntatore all'inizio della lista richiami la funzione init_list che semplicemente inizializza a NULL il puntatore (NULL sarà per noi come un segnale di fine lista). ogni volta che vorrai aggiungere un alemento in lista richiamerai la funzione insert_last che ti inserisce l'elemento in ultima posizione (o per lo meno, alla prima posizione == NULL). ricorda che per inserire un elemento in lista devi prima creare una nuova canzone (e quindi un nuovo oggetto di tipo struct song, oppure itemtype, che dir si voglia). io non ti ho scritto prima la funzione ma potrebbe essere una cosa del genere: Codice:
itemtype make_song (ptr lista, char *nome, char *aut, int lung) {
itemtype new;
strncpy (new.titolo, nome, 25);
strncpy (new.autore, aut, 25);
new.durata= lung;
// insert_last (lista, new);
return new;
}
|
|
|
|
|
|
|
#20 |
|
Senior Member
Iscritto dal: May 2001
Città: Monza
Messaggi: 4054
|
Siete davvero gentilissimi.......so di essere un pò ritardato su questi argomenti ma penso che infondo non siano poi tanto semplici.
Io pensavo che come dichiaravi un' array,con il c dichiarando una lista fosse già bella è pronta di dimesione scelta dalla malloc. Invece bisogna fare tutto manuale.....
__________________
Dostoevskij "La bellezza salverà il mondo" |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 21:58.



















