Newsgroup: it.comp.lang.c
Titolo: Nuovo esercizio

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


togli il ; dalle direttive define al preprocessore

 togli il ; dalle direttive define al preprocessore
 
ok, risolto grazie

 imbastire il programma vanno bene.
 
Per me è ok, forza vai avanti, ti aspettiamo.
 
-- 
Vincenzo Mercuri


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)
 
 
 
 
 

 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

       }
 
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

 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


 (sotto le SD come definite, le ho ripostate per praticità di consultazione)
[..]
 
Wow, questa si che è gentilezza :)
 
 
-- 
Vincenzo Mercuri


 
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

 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

 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

 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/
 


 
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