PDA

View Full Version : Aiuto per calloc (...eeeeC++...salute)


MetalMassacre
01-12-2002, 15:16
Ciao, sto giro devo scrivere un programma per la compilazione dell'agenda di impegni del giorno.
Il programma deve chiedere all'utente il numero di impegni previsti per la giornata.
Dovrà quindi creare dinamicamente un'agenda (un array di Impegni) e chiedere all'utente di riempirla inserendo gli impegni della giornata.

L'avevo inizialmente provato cosi....ma in questo modo mi sono accorto di non aver creato nessun array di impegni...tantomeno dinamicamente....



#include <stdlib.h>
#include <stdio.h>

typedef struct {int ore;
int minuti;} Orario;
typedef struct {Orario time;
char attivita;} Impegno;

int main()
{
int i,j=0;
Impegno impegno;
printf ("Quanti impegni hai oggi? ");
scanf ("%d", &i);
for (j=0; j<i; j++)
{
printf ("\nIl tuo %d° impegno di oggi e': ",j+1);
scanf ("%s", &(impegno.attivita));
printf ("Si terra' alle ore: ");
scanf ("%d", &(impegno.time.ore));
printf ("e quanti minuti? ");
scanf ("%d", &(impegno.time.minuti));
}

system("PAUSE");
return 0;
}



allora ho pensato di modificarlo così.....




#include <stdlib.h>
#include <stdio.h>

typedef struct {int ore;
int minuti;} Orario;
typedef struct {Orario time;
char attivita;} Impegno;

int main()
{
int i,j=0;
int *p;
Impegno impegno;
printf ("Quanti impegni hai oggi? ");
scanf ("%d", &i);
p=(Impegno*) calloc (i,sizeof(Impegno)); /*modifica*/
for (j=0; j<i; j++)
{
printf ("\nIl tuo %d° impegno di oggi e': ",j+1);
scanf ("%s", &(impegno.attivita));
printf ("Si terra' alle ore: ");
scanf ("%d", &(impegno.time.ore));
printf ("e quanti minuti? ");
scanf ("%d", &(impegno.time.minuti));
p[j]= ....... /*impegno?*/
}

system("PAUSE");
return 0;
}




dove ho messo ...... è perche non so come fare, volevo creare dinamicamente un array con calloc in modo da memorizzare su ogni blocco dell'array un impegno.
Suggerimenti?

è poi possibile memorizzare per ogni cella dell'array una variabile struttura di tipo Impegno (dato che raccoglie diversi tipi nel suo interno)?

MetalMassacre
01-12-2002, 16:07
Ragionandoci meglio mi e riuscito cosi...alloco dinamicamente ora?!? :D





#include <stdlib.h>
#include <stdio.h>

typedef struct {int ore;
int minuti;} Orario;
typedef struct {Orario time;
char attivita;} Impegno;

int main()
{
int i,j=0;
Impegno *p; /*rimodifica*/
Impegno impegno;
printf ("Quanti impegni hai oggi? ");
scanf ("%d", &i);
p=(Impegno*) calloc (i,sizeof(Impegno));
for (j=0; j<i; j++)
{
printf ("\nIl tuo %d° impegno di oggi e': ",j+1);
scanf ("%s", &(impegno.attivita));
printf ("Si terra' alle ore: ");
scanf ("%d", &(impegno.time.ore));
printf ("e quanti minuti? ");
scanf ("%d", &(impegno.time.minuti));
p[j]= impegno; /*rimodifica*/
}

system("PAUSE");
return 0;
}




è +o- giusto?

suggerite suggerite, dai che imparo...

ah cionci se passo l'esame in gennaio...verso l'estate passo dalle tue parti a offrirti uno spritz!!!

(se sai cos'è...):D :D :D

MetalMassacre
02-12-2002, 09:32
Nessuno ?

MetalMassacre
02-12-2002, 16:50
eee la peppa! :eek:

cionci
02-12-2002, 20:25
Cos'è uno spritz ? Mi devo preoccupare ?!?!?!?

Comuqnue qui...

printf ("\nIl tuo %d° impegno di oggi e': ",j+1);
scanf ("%s", &(impegno.attivita));
printf ("Si terra' alle ore: ");
scanf ("%d", &(impegno.time.ore));
printf ("e quanti minuti? ");
scanf ("%d", &(impegno.time.minuti));
p[j]= impegno;

...potevi anche usare direttamente p[j]...

Va bene anche così...ma è più logica una cosa del genere :

printf ("\nIl tuo %d° impegno di oggi e': ",j+1);
scanf ("%s", &(p[j].attivita));
printf ("Si terra' alle ore: ");
scanf ("%d", &(p[j].time.ore));
printf ("e quanti minuti? ");
scanf ("%d", &(p[j].time.minuti));

MetalMassacre
02-12-2002, 21:42
Originariamente inviato da cionci
[B]Cos'è uno spritz ? Mi devo preoccupare ?!?!?!?

Comuqnue qui...

printf ("\nIl tuo %d° impegno di oggi e': ",j+1);
scanf ("%s", &(impegno.attivita));
printf ("Si terra' alle ore: ");
scanf ("%d", &(impegno.time.ore));
printf ("e quanti minuti? ");
scanf ("%d", &(impegno.time.minuti));
p[j]= impegno;

...potevi anche usare direttamente p[j]...

Va bene anche così...ma è più logica una cosa del genere :

printf ("\nIl tuo %d° impegno di oggi e': ",j+1);
scanf ("%s", &(p[j].attivita));
printf ("Si terra' alle ore: ");
scanf ("%d", &(p[j].time.ore));
printf ("e quanti minuti? ");
scanf ("%d", &(p[j].time.minuti));



ascolta... perche p[j] ?? al posto di impegno?? ho molta confusione su questo argomento che abbiamo appena fatto....provo a rivederlo con calma ma è meglio se mi dai delle delucidazioni anche tu...domani andro in unive a fami spiegare meglio anche da loro...non lo trovo per niente facile sto discorso...
grazie intanto per l'attenzione...


PS:
spritz: miscela a base di prosecco + campari o aperol o altro...+ olivetta... taglia mooolto le gambe...(poi dipende chi te lo fa...) :D

cionci
03-12-2002, 02:37
Originariamente inviato da MetalMassacre
[B]spritz: miscela a base di prosecco + campari o aperol o altro...+ olivetta... taglia mooolto le gambe...(poi dipende chi te lo fa...) :D
A me non mi taglia niente le gambe ;)

L'unica volta che un cocktail mi ha tagliato le gambe...avevo detto al barman : "mettici quello che ti pare basta che sia la cosa più forte che tu abbia mai fatto"... Sono stato 4 ore senza sentire gusto in bocca :)

calloc instanzia riserva una zona di memoria per contenere una series di dati di dimensione i * sizeof(impegno)...
Dopo funziona come un vettore... Se p è il puntatore al vettore p[i] equivale ad *(p+i)...

MetalMassacre
03-12-2002, 10:26
Originariamente inviato da cionci
[B]
...Sono stato 4 ore senza sentire gusto in bocca :)



Bhe a differenza uno spritz non sprigiona tutta sta violenza...




ok...spetta... creo un array di impegni di tipo Impegni nella memoria dinamica con calloc;

allora quel puntatore p all'inizio è
p = &impegno [j]?? partendo con j=0



mi correggo...ho creato un array per variabili di tipo Impegno... p[j] indica ognuna delle celle di cui è composto l'array....con p[j].attività accedo direttamente al campo attività di quella cella j dell'array... ma l'array allora si chiama p?!? ma p poi non è un puntatore all prima cella dell'array..?!?


forse non ho ben chiaro sto discorso di array come puntatori...

MetalMassacre
03-12-2002, 16:00
di per se l'esercizio continua così...

Scrivere una funzione void ordina(Impegno *ag, int n) che data un agenda (cioè un array di Impegni) di dimensione n, riordina gli
impegni contenuti nell'agenda secondo l'ordine cronologico.

Ad esempio un'agenda ordinata è la seguente:
h. 8:00 sveglia
h. 11:00 tennis
h. 19:30 cinema
(Suggerimento: si usi uno degli algoritmi di ordinamento visti a
lezione).

ma non capisco nemmeno da dove partire o meglio cosa devo fare...ho capito che un agenda è un array di impegni...*ag che è?
avete idee piu chiare sul dafaris?

cionci
03-12-2002, 17:42
Originariamente inviato da MetalMassacre
[B]forse non ho ben chiaro sto discorso di array come puntatori...
In C c'è una relazione molto stretta fra array e puntatori ad una struttura allocata dinamicamente... Anzi...in pratica sono la stessa cosa...

int p[10];
int *q;

q = (int *)calloc(10, sizeof(int));

A questo punto p e q li usi alla stessa maniera !!! Solo devi ricordarti di fare il free di q...
L'unica cosa che non puoi fare a p (che di per sè è un int * che punta al primo elemento del vettore, non è IL VETTORE) è assegnargli un valore...cosa che invece a q posso fare (con la calloc ad esempio)...

Ad esempio :

*(p+1) = *q; /*assegno q[0] a p[1]*/
p[1] = q[0]; /*come sopra*/

Per il tuo esercizio...

void ordina(Impegno *ag, int n) è il prototipo della funzione di ordinamento che devi svilupare...

Il puntatore ag è il puntatore ad un elemento del vettore...ad esempio al primo...

Se io voglio rodinare "Impegni p[20]"... Richiamerò la ordina in questo modo :

ordina(p, 20);

Come ti ho spiegato prima p è un "Impegni *" !!! Scrivere Impegni *ag o Impegni ag[] è equivalente per il tuo scopo...

MetalMassacre
04-12-2002, 22:11
Originariamente inviato da cionci
[B]
In C c'è una relazione molto stretta fra array e puntatori ad una struttura allocata dinamicamente... Anzi...in pratica sono la stessa cosa...

int p[10];
int *q;

q = (int *)calloc(10, sizeof(int));

A questo punto p e q li usi alla stessa maniera !!! Solo devi ricordarti di fare il free di q...
L'unica cosa che non puoi fare a p (che di per sè è un int * che punta al primo elemento del vettore, non è IL VETTORE) è assegnargli un valore...cosa che invece a q posso fare (con la calloc ad esempio)...

Ad esempio :

*(p+1) = *q; /*assegno q[0] a p[1]*/
p[1] = q[0]; /*come sopra*/

Per il tuo esercizio...

void ordina(Impegno *ag, int n) è il prototipo della funzione di ordinamento che devi svilupare...

Il puntatore ag è il puntatore ad un elemento del vettore...ad esempio al primo...

Se io voglio rodinare "Impegni p[20]"... Richiamerò la ordina in questo modo :

ordina(p, 20);

Come ti ho spiegato prima p è un "Impegni *" !!! Scrivere Impegni *ag o Impegni ag[] è equivalente per il tuo scopo...


Ma continuo a non capire....
siccome devo dichiarere dinamicamente sta roba....
devo usare malloc (size of (agenda)) oppure calloc (n, size of(impegno)) ?? (credo di sapere la differenza tra questi...il primo alloca spazio per una variabile di tipo agenda il secondo n variabili di dimensione impegno....e un'agenda non è un array di impegni difatti???


solitamente mi credo un algoritmo in testa per vedere come fare gli esercizi ...ma sto giro non ne vado furi ...non comprendo come poter fare..:confused:

MetalMassacre
04-12-2002, 22:34
main
.......
......
k=(Impegno*) calloc (n, size of(Impegno));
ordina (&k, n);
.......
.......


void ordina (Impegno *ag, int n)
.......
.......



Possibile farlo così????
se si.... posso fare free p /*guarda il main del programma perchè sta seconda parte è correlata con la prima parte dell'exercizio*/
e usare p al posto di k??? o quello che c'e in p mi serve??cioe se freecco p non ho piu i dati che contiene e mando a putt... tutto?!?

cionci
05-12-2002, 09:02
Originariamente inviato da MetalMassacre
[B]

main
.......
......
k=(Impegno*) calloc (n, size of(Impegno));
ordina (&k, n);
.......
.......


void ordina (Impegno *ag, int n)
.......
.......



Possibile farlo così????
se si.... posso fare free p /*guarda il main del programma perchè sta seconda parte è correlata con la prima parte dell'exercizio*/
e usare p al posto di k??? o quello che c'e in p mi serve??cioe se freecco p non ho piu i dati che contiene e mando a putt... tutto?!?
NONE !! :D:D
k è già un Impegno * !!!
Non importa usare il dereference (&)...
In questo modo passi a ag l'indirizzo del puntatore... Invece devi passare l'indirizzo contenuto nel puntatore alla memoria allocata con calloc !!!

La differenza fra malloc e calloc è che calloc riempie di zero la memoria che alloca...

Potevi anche fare :

k = (Impegno*) malloc (n * sizeof(Impegno));

Poi per richiamare ordina fai in questo modo (sia con malloc che con calloc):

ordina(k, n);

Dentro la ordina usi ag come un normale vettore...ad ag volendo gli puoi passare anche un vettore allocato staticamente :

Impegno k[10];
...
ordina(k, n);

MetalMassacre
05-12-2002, 16:08
#include <stdlib.h>
#include <stdio.h>

typedef struct {int ore;
int minuti;} Orario;
typedef struct {Orario time;
char attivita;} Impegno;

void ordina (Impegno *ag, int n)
/*.........................................*/



int main()
{
int n,j=0;
Impegno *p,*k;
Impegno impegno;
printf ("Quanti impegni hai oggi? ");
scanf ("%d", &n);
p=(Impegno*) calloc (n,sizeof(Impegno));
for (j=0; j<n; j++)
{
printf ("\nIl tuo %d° impegno di oggi e': ",j+1);
scanf ("%s", &(impegno.attivita));
printf ("Si terra' alle ore: ");
scanf ("%d", &(impegno.time.ore));
printf ("e quanti minuti? ");
scanf ("%d", &(impegno.time.minuti));
p[j]= impegno;
}
k=(Impegno*) calloc (n,sizeof(Impegno));
ordina (k;n);



system("PAUSE");
return 0;
}



ora ho il mio puntatore ag che punta alla prima cella dell'array dinamico di dimensione n celle .... vero?

posso fare paragoni del tipo
ag [i].time.ora<ag[i+1].time.ora ???

puoi suggerirmi come implementare la ricerca per ordinare e stampare gli impegni in base all'ora...

cionci
05-12-2002, 16:16
Non capisco cosa stai facendo...perchè hai allocato anche k ?

Certo...puoi fare tutti i confronti che ti pare...

MetalMassacre
05-12-2002, 16:29
#include <stdlib.h>
#include <stdio.h>

typedef struct {int ore;
int minuti;} Orario;
typedef struct {Orario time;
char attivita;} Impegno;

void ordina (Impegno *ag, int n)
/*.........................................*/



int main()
{
int n,j=0;
Impegno *p;
Impegno impegno;
printf ("Quanti impegni hai oggi? ");
scanf ("%d", &n);
p=(Impegno*) calloc (n,sizeof(Impegno));
for (j=0; j<n; j++)
{
printf ("\nIl tuo %d° impegno di oggi e': ",j+1);
scanf ("%s", &(impegno.attivita));
printf ("Si terra' alle ore: ");
scanf ("%d", &(impegno.time.ore));
printf ("e quanti minuti? ");
scanf ("%d", &(impegno.time.minuti));
p[j]= impegno;
}

ordina (p;n);



system("PAUSE");
return 0;
}



meglio cosi?.....avevo lasciato in giro un po di roba...

un ciclo del genere fa al caso mio....??



for (i=0; i<=n; i++)
temp =p[i];
for (j=1; j<=n; j++)
if (temp<p[j])
p[i]=temp
else temp=p[j]

MetalMassacre
05-12-2002, 19:40
Ho fatto anche la 3^ parte dell exercizio che richiedeva:

Scrivere una funzione Orario cerca(Impegno *ag, int n, char *att) che
controlla se un dato impegno (identificato dalla stringa att) è previsto
nell'agenda di oggi, ritornandone l'orario. Se l'impegno non è previsto,
la funzione deve ritornare un orario negativo (es. _1 : _1).

puo andare una cosa del genere?





Orario cerca(Impegno *ag, int n, char *att)
{
int i;
for (i=0; i<=n; i++)
if (strcmp (ag[i].attivita, att) ==0 )
return ag[i].time
else printf ("-1:-1")
}



se fosse giusto (almeno concettualmente) come posso far ritornare -1:-1 senza "barare" con la printf???