Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Nuovo esercizio

38 views
Skip to first unread message

lucas

unread,
Apr 12, 2013, 6:01:53 AM4/12/13
to
Il precedente era troppo macchinoso da capire passo a questo simile, ma
più chiaro come testo.

**********************************************************
Negozio dei cellulari

Si consideri un archivio dei cellulari contenente 100 modelli conservato
in un archivio S:
Codice numerico del modello (progressivo univoco da 1 a 100)
Durata batteria
Peso
Prezzo acquisto
Numero totale di pezzi

Esistano 2 negozi, ognuno con il suo archivio del magazzino
(rispettivamente N1, N2 di MAX 1.000 elementi l'uno) dei cellulari arrivati:
Codice numerico del modello (lo stesso dell'archivio S)
Prezzo di vendita unitario
Numero pezzi arrivati di questo modelli

N.B.: di un modello possono arrivare anche 2 stock con differente numero
di pezzi

ESERCIZIO BASE

Scrivere in C un programma che:
1) Legge da tastiera le informazioni relative ai 100 modelli di
cellulari mettendo il numero totale a 0.
2) Legge da tastiera il nome del negozio e chiama una funzione
"magazzino" che legge da tastiera, in ordine casuale, ed inserisce
nell'archivio gli arrivi.
3) Chiama una funzione "aggiorna" S che aggiorna il numero totale di
pezzi arrivati nel negozio precedente nell'archivio dei cellulari S.
4) Chiama una funzione "ordina" che ordina gli archivi N1 ed N2 in base
al Prezzo di vendita unitario e rende il valore totale dei cellulari
presenti in quel magazzino.


ESERCIZIO 1

Inserire nel programma una funzione “Merce” che crea un vettore ordinato
in base al prezzo di vendita unitario in cui sono presenti gli articoli
di entrambi i negozi.

ESERCIZIO 2

Scrivere una funzione che costruisce 2 liste (L1 ed L2) contenenti
rispettivamente tutti cellulari presenti nel magazzino N1 con peso
superiore a 100 e minore di 100.

NB: le variabili usate devono essere locali e non è necessario
controllare la correttezza dei dati in input.
*************************************************************

Inizio col definire le SD, se mi dite che sono OK, proseguo con le funzioni

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

typedef struct {
int codice_modello;
int durata_batteria;
int peso;
int prezzo_acquisto;
int tot_pezzi_modello;} scheda_cellulare;

typedef struct {
scheda_cellulare cellulare;
int prezzo_vendita;
int pezzi_arrivati_modello;} scheda_magazzino;

#define Smax 100;
#define Nmax 1000;

typedef scheda_cellulare S[Smax];
typedef scheda_magazzino N[Nmax];

il compilatore mi dà questi errori in corrispondenza delle ultime 2 typedef:
expected `]' before ';' token
expected unqualified-id before ']' token
expected `,' or `;' before ']' token

non ho ben capito a cosa son dovuti gli errori, mi sembra che non
manchino dei ";".
Comunque in primis mi interessa capire se la definizione delle SD su cui
imbastire il programma vanno bene.
Grazie ciao

surrenderyourworld

unread,
Apr 12, 2013, 7:22:51 AM4/12/13
to
togli il ; dalle direttive define al preprocessore

lucas

unread,
Apr 12, 2013, 7:50:10 AM4/12/13
to
Il 12/04/2013 13.22, surrenderyourworld ha scritto:
> togli il ; dalle direttive define al preprocessore

ok, risolto grazie

Vincenzo Mercuri

unread,
Apr 12, 2013, 11:26:25 AM4/12/13
to
Il 12/04/2013 12:01, lucas ha scritto:
[..]
>
> Inizio col definire le SD, se mi dite che sono OK, proseguo con le funzioni
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>
> typedef struct {
> int codice_modello;
> int durata_batteria;
> int peso;
> int prezzo_acquisto;
> int tot_pezzi_modello;} scheda_cellulare;
>
> typedef struct {
> scheda_cellulare cellulare;
> int prezzo_vendita;
> int pezzi_arrivati_modello;} scheda_magazzino;
>
> #define Smax 100;
> #define Nmax 1000;

Aargh! :)

>
> typedef scheda_cellulare S[Smax];
> typedef scheda_magazzino N[Nmax];
>
[..]

> Comunque in primis mi interessa capire se la definizione delle SD su cui
> imbastire il programma vanno bene.

Per me è ok, forza vai avanti, ti aspettiamo.

--
Vincenzo Mercuri

enoquick

unread,
Apr 12, 2013, 10:39:05 PM4/12/13
to
Design pessimo,gli oggetti sono mischiati tutto nello stesso modulo

Se vuoi fare bella figura ti consiglio di strutturarlo a moduli


Gli oggetti esistenti sono cellulare, negozio, magazzino quindi tre
moduli con le sue funzioni (metodi in programmazione a oggetti)





lucas

unread,
Apr 16, 2013, 5:56:28 PM4/16/13
to
Il 12/04/2013 17.26, Vincenzo Mercuri ha scritto:
> Per me è ok, forza vai avanti, ti aspettiamo.

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

typedef struct {
int codice_modello;
int durata_batteria;
int peso;
float prezzo_acquisto;
int tot_pezzi_modello;} scheda_cellulare;

typedef struct {
scheda_cellulare c;
float prezzo_vendita;
int pezzi_arrivati_modello;} scheda_magazzino;

#define Smax 2
#define Nmax 2

typedef scheda_cellulare S[Smax];
typedef scheda_magazzino N[Nmax];

void leggi(S S1);
int magazzino(N Neg);
void stampaS(S S1);
void stampaN(N Neg);
void aggiorna(S S1,N Neg,int pezzi_arrivati_modello );
void ordinaInsertionSort(N Neg, int numero_arrivi);
void merce(N N1,N N2,int numero_arriviN1, int numero_arriviN2 );
void crealista(N Neg, int numero_arrivi);

int main() {
S S1={0};
N N1={0},N2={0};
char nome_negozio[3];
int numero_arriviN1=0;
int numero_arriviN2=0;
int done=0;
leggi(S1);
stampaS(S1);
do {
printf("Digita il nome del negozio nel quale vuoi inserire gli
arrivi\n");
scanf("%s",nome_negozio);
if(strcmp(nome_negozio,"N1")==0) {
numero_arriviN1=magazzino(N1);
done=1;}
else if(strcmp(nome_negozio,"N2")==0) {
numero_arriviN2=magazzino(N2);
done=1;}
else printf("Nome negozio errato, ridigitare\n");
} while(!done);
aggiorna(S1, N1, numero_arriviN1);
stampaS(S1);
ordinaInsertionSort(N1,numero_arriviN1);
stampaN(N1);
merce(N1,N2,numero_arriviN1,numero_arriviN2);
crealista(N1, numero_arriviN1);
system("PAUSE");
return 0;
}

void leggi(S S1) {
int i;
for(i=0;i<Smax;i++) {
S1[i].codice_modello=i+1;
printf("Inserire la durata batteria del modello cell %d\n",i+1);
scanf("%d",&S1[i].durata_batteria);
printf("Inserire il peso del modello cell %d\n",i+1);
scanf("%d",&S1[i].peso);
printf("Inserire il prezzo di acquisto del modello cell
%d\n",i+1);
scanf("%f",&S1[i].prezzo_acquisto);}
}

int magazzino(N Neg) {
int done=0;
char conferma[3];
int numero_arrivi=0;
int i=0;
do {
printf("Ci sono degli arrivi da inserire in magazzino? dgt SI
per conferma\n");
scanf("%s",conferma);
if(!strcmp(conferma,"SI")) {
printf("Inserire codice numerico dell'arrivo Nro
%d\n",i+1);
scanf("%d",&Neg[i].c.codice_modello);
printf("Inserire il prezzo di vendita dell'arrivo
Nro %d\n",i+1);
scanf("%f",&Neg[i].prezzo_vendita);
printf("Inserire il num di pezzi arrivati
dell'arrivo Nro %d\n",i+1);
scanf("%d",&Neg[i].pezzi_arrivati_modello);
numero_arrivi++;
i++;}
else
done=1;
} while(!done);
return numero_arrivi;
}


void aggiorna(S S1, N Neg, int pezzi_arrivati_modello) {
int i,j=0;

for(i=0;i<Smax;i++)
for(j=0;j<pezzi_arrivati_modello;j++)
if(Neg[j].c.codice_modello==i+1)
S1[i].tot_pezzi_modello+=Neg[j].pezzi_arrivati_modello;
}


void ordinaInsertionSort(N Neg, int numero_arrivi) {
int i,j;
N tmp;
int num_cell_totali=0;
for (i=1;i<numero_arrivi;i++)
{
tmp[i]=Neg[i];
for (j= i-1;(j>=0) &&
(Neg[j].prezzo_vendita>tmp[i].prezzo_vendita);j--)
Neg[j+1]=Neg[j];
Neg[j+1]=tmp[i];
}
for(i=0;i<numero_arrivi;i++)
num_cell_totali+=Neg[i].pezzi_arrivati_modello;
printf("Il numero totale di cellulari arrivati in magazzino è:
%d\n",num_cell_totali);
}

void merce(N N1,N N2,int numero_arriviN1, int numero_arriviN2 ) {
int arrivi_totali=numero_arriviN1+numero_arriviN2;
int v[arrivi_totali];
int i,j;
scheda_magazzino Neg[arrivi_totali];
scheda_magazzino tmp[arrivi_totali];
for(i=0;i<numero_arriviN1;i++)
Neg[i]=N1[i];
for(i=numero_arriviN1;i<arrivi_totali;i++)
Neg[i]=N2[i-numero_arriviN1];
for(i=0;i<arrivi_totali;i++) {
printf("\n\nCodice modello:%d, prezzo vendita:%f, tot
pezzi:%d\n\n",

Neg[i].c.codice_modello,Neg[i].prezzo_vendita,Neg[i].pezzi_arrivati_modello);}
for (i=1;i<arrivi_totali;i++)
{
tmp[i]=Neg[i];
for (j= i-1;(j>=0) &&
(Neg[j].prezzo_vendita>tmp[i].prezzo_vendita);j--)
Neg[j+1]=Neg[j];
Neg[j+1]=tmp[i];
}
for(i=0;i<arrivi_totali;i++)
v[i]=Neg[i].c.codice_modello;
}


struct nodo{
scheda_magazzino cellulare;
struct nodo *next;};


void crealista(N Neg, int numero_arrivi) {
struct nodo *testaL1;
struct nodo *nuovoElementoL1;
testaL1=NULL;
struct nodo *testaL2;
struct nodo *nuovoElementoL2;
testaL2=NULL;
int i;
for(i=0;i<numero_arrivi;i++) {
if(Neg[i].c.peso>100)
{
nuovoElementoL1=(struct nodo*)malloc(sizeof(struct nodo));
nuovoElementoL1->cellulare=Neg[i];
nuovoElementoL1->next=testaL1;
testaL1=nuovoElementoL1;
}
else if(Neg[i].c.peso<100)
{
nuovoElementoL2=(struct nodo*)malloc(sizeof(struct nodo));
nuovoElementoL2->cellulare=Neg[i];
nuovoElementoL2->next=testaL2;
testaL2=nuovoElementoL2;
}
}
struct nodo *tmp;
tmp=testaL1;
while(tmp!=NULL)
{
printf("%d ",tmp->cellulare.c.codice_modello);
tmp=tmp->next;
}
}


void stampaS(S S1) {
int i=0;
for(i=0;i<Smax;i++) {
printf("\n\nCodice modello:%d, durata batteria:%d, peso:%d,
prezzo acquisto:%f, tot pezzi:%d\n\n",

S1[i].codice_modello,S1[i].durata_batteria,S1[i].peso,S1[i].prezzo_acquisto,S1[i].tot_pezzi_modello);}
}

void stampaN(N Neg) {
int i=0;
for(i=0;i<Nmax;i++) {
printf("\n\nCodice modello:%d, prezzo vendita:%f, tot
pezzi:%d\n\n",

Neg[i].c.codice_modello,Neg[i].prezzo_vendita,Neg[i].pezzi_arrivati_modello);}
}


La funzione "crealista" non funziona, deve esserci un errore negli if ma
non sono riuscito a trovarlo.
Per il resto funziona anche se sicuramente ci saranno state soluzioni
migliori per risolvere l'esercizio.
Grazie ciao

Vincenzo Mercuri

unread,
Apr 18, 2013, 10:29:31 PM4/18/13
to
On 16/04/2013 23:56, lucas wrote:
[..]

Guarda ho dato un'occhiata al programma, mentirei se ti dicessi che l'ho
studiato attentamente, ma grosso modo puo' andare. Ci sono alcuni punti
oscuri nella funzione "crealista()" specie per quanto riguarda la
creazione/inserimento dei nodi, che francamente ti consiglio di implementa-
re come funzioni separate. Ti consiglio poi di rendere più robusto il
programma quando si tratta di leggere l'input da tastiera, altrimenti al
minimo errore è tutto da rifare (grande scocciatura se le schede diventano
più di 2..). Sintatticamente mi è sembrato un grosso miglioramento rispet-
to al codice che avevi scritto prima, solo un dubbio sul fatto che in
pratica stai usando il C99 e sei su Windows. Sei sicuro che il prof. dia
per scontato l'utilizzo di una delle ultime versioni di gcc su Windows?
Non per altro, se lo compili con Visual C++ ti dà una serie di errori per
via dello Standard diverso che supporta (il C90). Ti consiglio, se sei
nel dubbio, di prescindere dal C99 e non mescolare dichiarazioni ad inizia-
lizzazioni, poi quella "struct nodo" lì in mezzo al codice è assolutamente
da evitare. Il codice è piccolo ed è ancora visibile ma se aggiungi qualche
altra funzione la perdi di vista. Tutte le dichiarazioni ti consiglio di
raggrupparle all'inizio, e poi trattandosi di un "tipo" ti consiglio di
usare
una lettera maiuscola, come "Nodo" (si anche se nei libri non è sempre
così), lasciamo le lettere minuscole iniziali per le variabili.

> void crealista(N Neg, int numero_arrivi) {
> struct nodo *testaL1;
> struct nodo *nuovoElementoL1;
> testaL1=NULL;
> struct nodo *testaL2;
> struct nodo *nuovoElementoL2;
> testaL2=NULL;
> int i;

vedi mi riferisco a punti come questo: sono mischiate dichiarazioni e
definizioni, questo è permesso nel C99 e C11, ma non negli Standard passati.

> for(i=0;i<numero_arrivi;i++) {
> if(Neg[i].c.peso>100)
> {
> nuovoElementoL1=(struct nodo*)malloc(sizeof(struct nodo));
> nuovoElementoL1->cellulare=Neg[i];
> nuovoElementoL1->next=testaL1;
> testaL1=nuovoElementoL1;
> }
> else if(Neg[i].c.peso<100)
> {
> nuovoElementoL2=(struct nodo*)malloc(sizeof(struct nodo));
> nuovoElementoL2->cellulare=Neg[i];
> nuovoElementoL2->next=testaL2;
> testaL2=nuovoElementoL2;
> }
> }

devi sempre, Sempre, SEMPRE, testare il successo di una allocazione di
memoria con malloc(). Se per qualche motivo l'allocazione fallisce puoi
causare un terremoto. Ti consiglio di suddividere il problema, in
crealista()
semplicemente devi inizializzare le teste a NULL e poi usi le funzioni
"aggiungiNodo()", per esempio. Che poi, se le liste devono essere due
perchè si chiama "crealista()"? Il nome deve essere sempre coerente e deve
descrivere bene le operazioni che fa. Se fai una funzione crealista()
allora crea davvero una sola lista e poi chiami la funzione due volte.
Poi di norma tutto quello che allochi lo dovresti deallocare. Siccome qui
si tratta di inezie (piccolissime quantità di memoria) e siccome appena
crei le liste in pratica esci dal programma, potresti anche non liberare
la memoria allocata dinamicamente. Di solito, all'uscita di un processo
il sistema operativo rilascia la memoria dinamica da esso allocata.
Ma se avessi dovuto fare altre operazioni piuttosto onerose (tipo caricare
un grande stack di immagini in memoria) dopo la creazione anche di una
lista piccola, avresti dovuto si badare a liberarla. In ogni caso è buona
norma farlo, e non delegare sempre al sistema operativo quest'operazione.

--
Vincenzo Mercuri

lucas

unread,
Apr 19, 2013, 5:34:14 AM4/19/13
to
Il 19/04/2013 4.29, Vincenzo Mercuri ha scritto:

> Guarda ho dato un'occhiata al programma, mentirei se ti dicessi che l'ho
> studiato attentamente, ma grosso modo puo' andare. Ci sono alcuni punti

[...]

ciao, ho letto e capito (credo al 95%) le tue osservazioni e vedrò di
metterle in pratica, magari in un altro reply ti chiederò lumi sulle
cose che hai scritto e che non ho ben capito.

Ora mi preme cercare di capire un'altra cosa. Ho capito perchè la
creazione della lista non avviene: è perchè il vettore Neg[i].c.peso non
è inizializzato (o meglio è inizializzato a zero nel main e infatti se
metto "Neg[i].c.peso==0" la lista viene creata).

Io ho inizializzato il vettore S1[i].peso, ma forse non è corretto.

Quindi ricapitolando, _forse_ il vettore su cui scrivere i dati nei vari
punti dell'esercizio è sempre N[i] . Ad esempio la funzione leggi che io
avevo scritto come


void leggi(S S1) {
int i;
for(i=0;i<Smax;i++) {
S1[i].codice_modello=i+1;
printf("Inserire la durata batteria del modello cell %d\n",i+1);
scanf("%d",&S1[i].durata_batteria);
printf("Inserire il peso del modello cell %d\n",i+1);
scanf("%d",&S1[i].peso);
printf("Inserire il prezzo di acquisto del modello cell
%d\n",i+1);
scanf("%f",&S1[i].prezzo_acquisto);}
}


probabilmente andrebbe riscritta sostituendo al posto di S1[i] , N1[i].c
e il prototipo sarebbe
void leggi(N N1);

Che ne dici?
Grazie

(sotto le SD come definite, le ho ripostate per praticità di consultazione)


typedef struct {
int codice_modello;
int durata_batteria;
int peso;
float prezzo_acquisto;
int tot_pezzi_modello;} scheda_cellulare;

typedef struct {
scheda_cellulare c;
float prezzo_vendita;
int pezzi_arrivati_modello;} scheda_magazzino;

#define Smax 100
#define Nmax 1000

Vincenzo Mercuri

unread,
Apr 19, 2013, 11:26:57 AM4/19/13
to
On 19/04/2013 11:34, lucas wrote:
> Il 19/04/2013 4.29, Vincenzo Mercuri ha scritto:
>
>> Guarda ho dato un'occhiata al programma, mentirei se ti dicessi che l'ho
>> studiato attentamente, ma grosso modo puo' andare. Ci sono alcuni punti
>
> [...]
>
> ciao, ho letto e capito (credo al 95%) le tue osservazioni e vedrò di
> metterle in pratica, magari in un altro reply ti chiederò lumi sulle
> cose che hai scritto e che non ho ben capito.
>
> Ora mi preme cercare di capire un'altra cosa. Ho capito perchè la
> creazione della lista non avviene: è perchè il vettore Neg[i].c.peso non
> è inizializzato (o meglio è inizializzato a zero nel main e infatti se
> metto "Neg[i].c.peso==0" la lista viene creata).
>

Se è inizializzato o meno non credo sia quello il problema, se crei tanti
elementi della lista quanto è il numero di arrivi, evidentemente ti ritrovi
con elementi già inizializzati (dai tu le coordinate da tastiera). Penso
piuttosto che il problema sia quando si tratta di inserire il numero di
arrivi, qualcosa deve andare storto lì.

Per la creazione della lista avevo pensato a qualcosa del genere:

struct nodo* aggiungiNodo(struct nodo *testa, scheda_magazzino cell)
{
struct nodo *n = (struct nodo *) malloc(sizeof (struct nodo));
if(n == NULL) {
fprintf(stderr, "Errore: malloc() non ha potuto creare un nodo\n");
exit(EXIT_FAILURE);
}
if (testa == NULL) testa = n; /* per il primo elemento */
n->cellulare = cell;
n->next = NULL;
return n;
}

struct nodo* creaLista1(N Neg, int numero_arrivi)
{
int i;
for(i = 0; i < numero_arrivi; i++) {
if(Neg[i].c.peso > 100) {
lista1 = aggiungiNodo(lista1, Neg[i]);
}
return lista1;
}
}

struct nodo* creaLista2(N Neg, int numero_arrivi)
{
int i;
for(i = 0; i < numero_arrivi; i++) {
if(Neg[i].c.peso <= 100) {
lista2 = aggiungiNodo(lista2, Neg[i]);
}
return lista2;
}
}

void stampaLista(struct nodo *n)
{
if(n == NULL) {
fprintf(stderr, "Lista vuota, niente da stampare!\n");
}
while(n != NULL) {
printf("\nCodice modello: %d\nDurata batteria: %d\n"
"Peso: %d\nPrezzo acquisto: %f\n",
n->cellulare.c.codice_modello,
n->cellulare.c.durata_batteria,
n->cellulare.c.peso, n->cellulare.c.prezzo_acquisto);
n = n->next;
}
putchar('\n');
}

dove in pratica suddividi il problema e aggiungi i nodi in coda, cosa
che secondo me è più adatta, vista la natura semplice del problema.
Poi ho un dubbio sul fatto che il nodo debba contenere davvero la copia
dell'intera struttura. Perchè non solo il puntatore? In realtà ogni scheda
è già in un array, la tua lista in effetti non ha bisogno di contenere
i dati veri e propri, ma i puntatori ad essi. Comunque quest'ultima parte
puoi tralasciarla se non è richiesta.

In pratica poi dovresti strutturare un main() in questo modo:

[..]
struct nodo {
scheda_magazzino cellulare;
struct nodo *next;
};

/* ecco io qui dicevo, è necessario usare tutta la struttura?
* secondo me no, potresti semplicemente scrivere:
*
* scheda_magazzino *cellulare;
*
* tanto gli elementi della lista basta che li fai puntare agli
* elementi dell'array. Certo poi dovresti cambiare il codice,
* quindi per adesso lascia stare.
*/

/* è più logico secondo me che le liste siano puntatori globali */

struct nodo *lista1 = NULL; /* il NULL qui è facoltativo, ma non nuoce */
struct nodo *lista2 = NULL;

void stampaLista(struct nodo * n);
struct nodo* creaLista1(N Neg, int numero_arrivi);
struct nodo* creaLista2(N Neg, int numero_arrivi);
struct nodo* aggiungiNodo(struct nodo *testa, scheda_magazzino cell);
[..]

int main(void)
{
/*...*/
lista1 = creaLista1(N1, numero_arriviN1);
lista2 = creaLista2(N1, numero_arriviN1);
stampaLista(lista1);
stampaLista(lista2);
system("PAUSE");
return 0;
}


> Io ho inizializzato il vettore S1[i].peso, ma forse non è corretto.
> void leggi(S S1) {
[..]
> probabilmente andrebbe riscritta sostituendo al posto di S1[i] , N1[i].c
> e il prototipo sarebbe
> void leggi(N N1);

Questo dipende dal testo.. a me pare che parli solo di S, ma ancora
ho seri dubbi su cosa chieda. Comunque a questo punto è solo un fatto
di interpretazione, l'importante è che hai capito come si stampano
le informazioni.

[..]
> (sotto le SD come definite, le ho ripostate per praticità di consultazione)
[..]

Wow, questa si che è gentilezza :)


--
Vincenzo Mercuri

Vincenzo Mercuri

unread,
Apr 19, 2013, 11:59:39 AM4/19/13
to
On 19/04/2013 17:26, Vincenzo Mercuri wrote:
[..]
> Per la creazione della lista avevo pensato a qualcosa del genere:
>
> struct nodo* aggiungiNodo(struct nodo *testa, scheda_magazzino cell)
> {
> struct nodo *n = (struct nodo *) malloc(sizeof (struct nodo));
> if(n == NULL) {
> fprintf(stderr, "Errore: malloc() non ha potuto creare un
> nodo\n");
> exit(EXIT_FAILURE);
> }
> if (testa == NULL) testa = n; /* per il primo elemento */
> n->cellulare = cell;
> n->next = NULL;
> return n;
> }
>

Si vabè qui ho saltato la connessione alla coda, te la riscrivo qui:

struct nodo* aggiungiNodo(struct nodo *testa, struct nodo *coda,
scheda_magazzino cell)
{
struct nodo *n = (struct nodo *) malloc(sizeof(struct nodo));

if(n == NULL) {
fprintf(stderr, "Errore: malloc() non ha potuto creare un nodo\n");
exit(EXIT_FAILURE);
}

n->cellulare = cell;
n->next = NULL;

if(testa == NULL) /* per il primo nodo */
testa = n;
else
coda->next = n; /* per gli altri nodi */
coda = n;

return n;
}

Va bene, ti ho solo complicato la vita ora, anche perchè il resto del
codice andrebbe cambiato in corrispondenza. Se ti trovi meglio con
l'inserimento in testa forse è meglio non cambiare adesso. Mi trovo meglio
a inserire in coda in una lista semplice perchè il "next" ha proprio
il significato di successivo, anche cronologicamente. Questione di gusti
in questo caso. Perdonami se ho aumentato la confusione.

--
Vincenzo Mercuri

Enrico Franchi

unread,
Apr 22, 2013, 4:48:11 PM4/22/13
to
Vincenzo Mercuri <vincenzo...@yahoo.it> wrote:
> Sei sicuro che il prof. dia
> per scontato l'utilizzo di una delle ultime versioni di gcc su Windows?
> Non per altro, se lo compili con Visual C++ ti dà una serie di errori per
> via dello Standard diverso che supporta (il C90). Ti consiglio, se sei
> nel dubbio, di prescindere dal C99 e non mescolare dichiarazioni ad inizia-
> lizzazioni, ->

Io credo che il punto sia un altro... da qualche parte nel corso e' stato
detto, probabilmente, a che standard C si riferiscono. O per lo meno si e'
visto se certe cose sono ammesse o meno (dagli esempi).

Per il resto, posso essere d'accordo che programmare in C99 per mischiare
dichiarazioni e statement non sia una grande idea. Pero' credo che C99
abbia introdotto numerose cose che e' un peccato non usare: in particolare,
a meno di input diverso, io assumerei di avere a disposizione C99.

Non conosco universita' che forzano l'uso di VC++. Di solito, ormai, il
compilatore di default e' gcc.


--
-riko

Vincenzo Mercuri

unread,
Apr 22, 2013, 8:55:19 PM4/22/13
to
On 22/04/2013 22:48, Enrico Franchi wrote:
> Vincenzo Mercuri <vincenzo...@yahoo.it> wrote:
>> Sei sicuro che il prof. dia
>> per scontato l'utilizzo di una delle ultime versioni di gcc su Windows?
>> Non per altro, se lo compili con Visual C++ ti dà una serie di errori per
>> via dello Standard diverso che supporta (il C90). Ti consiglio, se sei
>> nel dubbio, di prescindere dal C99 e non mescolare dichiarazioni ad inizia-
>> lizzazioni, ->
>
> Io credo che il punto sia un altro... da qualche parte nel corso e' stato
> detto, probabilmente, a che standard C si riferiscono. O per lo meno si e'
> visto se certe cose sono ammesse o meno (dagli esempi).
>

Questo è vero, ci ho pensato in realtà, sarebbe strano in effetti che
uno studente prendesse l'iniziativa di cambiare l'ordine delle dichiara-
zioni. Devo dire che sono felice che in Italia ci siano corsi fondamentali
di informatica basati sul più moderno C99. Ho voluto piuttosto seminare
un po' il dubbio sulla correttezza delle dichiarazioni perchè, anche se
uno studente si fa tutte quelle ore di esercitazione, puo' essere che non
si renda mai conto di che Standard del linguaggio stia usando. Ora, puo'
succedere che si trovi a usare un altro compilatore, come appunto il Visual
C++ (magari in versione Express, scaricabile gratuitamente) e in tal caso
si domanderebbe cosa non va col suo programma. Immagina lo sconcerto se
non dovesse essere bene a conoscenza della differenza C90/C99. Oppure
immagina compilatori per sistemi embedded, molti sono ancora conformi al
solo C90. Se non altro essere consapevole di non aver sbagliato linguaggio,
ma solo lo Standard, è una conquista che avrebbe dovuto fare prima o poi.

> Per il resto, posso essere d'accordo che programmare in C99 per mischiare
> dichiarazioni e statement non sia una grande idea. Pero' credo che C99
> abbia introdotto numerose cose che e' un peccato non usare: in particolare,
> a meno di input diverso, io assumerei di avere a disposizione C99.
>

Certo, potessi scegliere.. C99 mille volte.

> Non conosco universita' che forzano l'uso di VC++. Di solito, ormai, il
> compilatore di default e' gcc.

Si questo è vero, e spero sia così dappertutto, specialmente per i corsi
introduttivi alla programmazione. Tuttavia in laboratorio le cose si
fanno un po' più complicate perchè bisogna usare quello di cui si dispone.
Per esempio l'sdk che usavo per programmare una videocamera era scaricabile
gratuitamente, ma era una libreria in C a codice chiuso, da integrare in
Visual Studio 2010, che fortunatamente il laboratorio aveva. Ma niente C99..

--
Vincenzo Mercuri

Enrico Franchi

unread,
Apr 30, 2013, 1:48:00 PM4/30/13
to
Vincenzo Mercuri <vincenzo...@yahoo.it> wrote:

> Questo � vero, ci ho pensato in realt�, sarebbe strano in effetti che
> uno studente prendesse l'iniziativa di cambiare l'ordine delle dichiara-
> zioni.

Guarda... non hai nemmeno idea della fantasia che hanno.
Non importa quanto ben strutturata e' la programmazione che gli fai. Ci
sono sempre quelli che "ne sanno di piu'" e introducono obrobri, vuoi
come residuo delle superiori, vuoi perche' glielo ha detto l'amico che
ne sa di piu'.

Poi c'e' la semplice inventiva.

Per esempio, ad ogni sessione salta fuori almeno un if a tre vie.
Ovvero, in un diagramma di flusso, salta fuori un costrutto condizionale
ternario. Ma che sia chiaro, non e' una questione tipo "se == a, di qui,
se = b di la, altrimenti di la ancora". Cioe' non e' un'invenzione
sintattica per rappresentare uno switch o un if annidato (cosa che non
sarebbe *troppo* grave). E' proprio un "non ho capito il concetto di
if".

> Devo dire che sono felice che in Italia ci siano corsi fondamentali
> di informatica basati sul pi� moderno C99.

E' possibile che qualcosa ci sia. In generale, chi fa ancora C, tende a
fare C++. Nel senso che nel primo corso di programmazione invece che
fare semplice C, fanno il sottoinsieme di C++ relativamente compatibile
con C.

In realta' spesso i problemi sono tali che passi sopra anche a cose come
array statici allocati con parametro da funzione, che g++ normalmente
digerisce (e che mutua da C99, ma che in C++98 non ci sarebbe).

La mia idea e' che, semplicemente, le regole formali non siano troppo
severe e che semplicemente quello che compilano con gcc "va bene".


> Ho voluto piuttosto seminare
> un po' il dubbio sulla correttezza delle dichiarazioni perch�, anche se
> uno studente si fa tutte quelle ore di esercitazione, puo' essere che non
> si renda mai conto di che Standard del linguaggio stia usando.

Lo studente medio non ha *neppure* idea che esista uno standard. Le cose
che gli vengono dette, rimangono al 10%. Spesso non rimane nemmeno il
concetto di unita' di traduzione, perche' per buona parte delle
esercitazioni (se non tutte), lavorano su un solo file. E cosi' via.



> Ora, puo'
> succedere che si trovi a usare un altro compilatore, come appunto il Visual
> C++ (magari in versione Express, scaricabile gratuitamente) e in tal caso
> si domanderebbe cosa non va col suo programma.

Che io sappia, ormai sono quasi tutti su gcc, eventualmente con quel
cesso del vecchio dev-cpp con compilatore ante-guerra.

> Immagina lo sconcerto se
> non dovesse essere bene a conoscenza della differenza C90/C99. Oppure
> immagina compilatori per sistemi embedded, molti sono ancora conformi al
> solo C90. Se non altro essere consapevole di non aver sbagliato linguaggio,
> ma solo lo Standard, � una conquista che avrebbe dovuto fare prima o poi.

Forse alla magistrale. O se ha qualche progetto mirato anche prima, ma
altrimenti...
potessi scegliere.. C99 mille volte.
>
> > Non conosco universita' che forzano l'uso di VC++. Di solito, ormai, il
> > compilatore di default e' gcc.
>
> Si questo � vero, e spero sia cos� dappertutto, specialmente per i corsi
> introduttivi alla programmazione. Tuttavia in laboratorio le cose si
> fanno un po' pi� complicate perch� bisogna usare quello di cui si dispone.

Noi abbiamo installato codeblocks e devcpp. Quindi sotto in ambo i casi
c'e' un gcc, relativamente moderno con uno, meno con l'altro. Ad
ingegneria invece c'e' direttamente Qt-Creator, perche' una parte del
corso la fanno usando Qt.


--
-riko
http://www.enrico-franchi.org/
http://rik0-techtemple.blogspot.com/

Vincenzo Mercuri

unread,
May 3, 2013, 12:45:10 PM5/3/13
to
Il 30/04/2013 19:48, Enrico Franchi ha scritto:
> Vincenzo Mercuri <vincenzo...@yahoo.it> wrote:
>
>> Questo � vero, ci ho pensato in realt�, sarebbe strano in effetti che
>> uno studente prendesse l'iniziativa di cambiare l'ordine delle dichiara-
>> zioni.
>
> Guarda... non hai nemmeno idea della fantasia che hanno.
> Non importa quanto ben strutturata e' la programmazione che gli fai. Ci
> sono sempre quelli che "ne sanno di piu'" e introducono obrobri, vuoi
> come residuo delle superiori, vuoi perche' glielo ha detto l'amico che
> ne sa di piu'.
>
> Poi c'e' la semplice inventiva.
>
> Per esempio, ad ogni sessione salta fuori almeno un if a tre vie.
> Ovvero, in un diagramma di flusso, salta fuori un costrutto condizionale
> ternario. Ma che sia chiaro, non e' una questione tipo "se == a, di qui,
> se = b di la, altrimenti di la ancora". Cioe' non e' un'invenzione
> sintattica per rappresentare uno switch o un if annidato (cosa che non
> sarebbe *troppo* grave). E' proprio un "non ho capito il concetto di
> if".
>

Devo dire che mi ha fatto sorridere questa parte.. � verissimo quello
che dici, stessa cosa in matematica.. a volte mi ritrovo regole auree
mai inventate o scoperte.. ma c'� sempre qualcuno che � pi� geniale
dello stesso Gauss.. peccato che..


>> Devo dire che sono felice che in Italia ci siano corsi fondamentali
>> di informatica basati sul pi� moderno C99.
>
> E' possibile che qualcosa ci sia. In generale, chi fa ancora C, tende a
> fare C++. Nel senso che nel primo corso di programmazione invece che
> fare semplice C, fanno il sottoinsieme di C++ relativamente compatibile
> con C.

Ecco, personalmente sono contrarissimo a questo.. cio� sono a favore
dell'insegnamento del C come C e del C++ gi� nell'ottica della programma-
zione a oggetti.. ma apprendere il "sottoinsieme" del C++ pi� compatibile
al C e insegnarlo come C � un errore grave secondo me. Inculca strane e
assurde idee sul cosiddetto "C/C++", linguaggio che non esiste.
Le differenze fra i due linguaggi sono tante, anche piuttosto sottili.

>
> In realta' spesso i problemi sono tali che passi sopra anche a cose come
> array statici allocati con parametro da funzione, che g++ normalmente
> digerisce (e che mutua da C99, ma che in C++98 non ci sarebbe).
>
> La mia idea e' che, semplicemente, le regole formali non siano troppo
> severe e che semplicemente quello che compilano con gcc "va bene".
>

Secondo me per esempio, non sarebbe male insegnare il C come del resto
lo abbiamo imparato noi, cio� prima come C90 (almeno questo � il primo
che ho imparato io) e poi C99. Quindi sarebbe ottimo fare una prima
parte del corso compilando con "-ansi -pedantic" e poi con "-std=c99".
Sarebbe gi� un modo efficace di insegnare la differenza tra gli Standard.

>
>> Ho voluto piuttosto seminare
>> un po' il dubbio sulla correttezza delle dichiarazioni perch�, anche se
>> uno studente si fa tutte quelle ore di esercitazione, puo' essere che non
>> si renda mai conto di che Standard del linguaggio stia usando.
>
> Lo studente medio non ha *neppure* idea che esista uno standard. Le cose
> che gli vengono dette, rimangono al 10%. Spesso non rimane nemmeno il
> concetto di unita' di traduzione, perche' per buona parte delle
> esercitazioni (se non tutte), lavorano su un solo file. E cosi' via.
>
>

Ahaha.. verissimo


[..]
>
> Noi abbiamo installato codeblocks e devcpp. Quindi sotto in ambo i casi
> c'e' un gcc, relativamente moderno con uno, meno con l'altro. Ad
> ingegneria invece c'e' direttamente Qt-Creator, perche' una parte del
> corso la fanno usando Qt.
>

Fantastico, le Qt sono meravigliose, peccato per il fatto di doversele
compilare da s� per il supporto nativo OpenGL nella versione 5 a 64-bit.
Sicuramente gi� le conoscerai, ma ci sono diverse release su internet
che magari puoi mettere a disposizione dei tuoi studenti se volessi un
gcc all'ultimo grido:

http://nuwen.net/mingw.html (la mia preferita)

http://sourceforge.net/projects/mingwbuilds/files/host-windows/releases/4.8.0/


Se hanno l'accortezza di sovrascrivere il mingw di codeblocks/devcpp
non devono neanche cambiare delle impostazioni, oppure volendo, si possono
tenere due versioni senza problemi.

E poi ci sono le release di Gcc a 64-bit, che possono interessare a
qualcuno che magari ha in mente un progetto ambizioso di elaborazione
di immagini:

http://tdm-gcc.tdragon.net/download

che si integra bene col dev-c++ di Orwell:

http://orwelldevcpp.blogspot.it/


--
Vincenzo Mercuri
0 new messages