[C] Chiarimenti utilizzo coda

franbisc
Ho questo esercizio in cui si chiede d implementare un programma Produttore/Consumatore che gestisce un magazzino di stoccaggio. L'utente può immettere P e nome del pezzo se vuole inserire in magazzino un elemento , oppure C se vuole ricevere un pezzo presente in magazzino.Poi si deve stampare a video il nome del pezzo consegnato. I pezzi presenti in magazzino vanno riconsegnati in ordine di produzione
Il codice è questo:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int Item;

Item *q;
int N, head, tail;

void queue_init(int maxN) {
   N = maxN+1;
   q = malloc(N*sizeof(Item));
   head=0;
   tail=0;
 }

int queue_empty() {
  return head%N == tail;
 }

int queue_full() {
  return (tail+1)%N == head%N;
 }

void queue_put(Item item) {
   q[tail++] = item;
   tail=tail%N; 
 }

Item queue_get() {
    head = head%N;
    return q[head++];
 }




int main(int argc, char *argv[])
{
  int N = atoi(argv[1]);
  queue_init(N);
  char operazione;
  char pezzo[25];
  int el;
  
  printf("CODA di dimensione %d\n",N);
  printf("P per aggiungere un pezzo in magazzino");
  printf(",c per riceverlo, exit per terminare:\n");

  while(1)
  {
     operazione=getch();
     switch(operazione)
     {
     case'p':                
        {
        if (queue_full())
          printf("\nMagazzino pieno\n");
        else
        {
          printf("Inserire il nome del pezzo: ");
          scanf("%s",pezzo);
          printf("Hai inserito in magazzino :%s \n",pezzo);
          el=malloc(strlen(pezzo)+1);
          strcpy(el,pezzo);
          queue_put(el);
        }
        break; 
        }

     case 'c':      
        {
          if(queue_empty())  printf("\nMagazzino vuoto!!\n");
          else
           {
             Item tmp= queue_get();
             printf("Hai prelevato in magazzino :%s \n",tmp);
             free(tmp);
           }
        break; 
        }
        case 27:
        return; 
    break;
    }
}
  system("PAUSE");
  return 0;
}


Per scrivere questo codice ho preso spunto da un altro esercizio svolto dal professore,in cui la gestione di una coda che doveva contenere stringhe veniva fatta così,cioè l'item era comunque un int.Ora vi chiedo di chiarirmi alcune cose:

in pratica ho capito che si usa il typedef int Item per la riusabilità del codice è perchè comunque in C anche le stringhe sono array di caratteri,e i singoli char sono int limitati nel valore che possono assumere...giusto?
Ma non riesco a capire come può funzionare questo programma,cioè ad esempio nella funzione che inizializza la dimensione della coda:
void queue_init(int maxN) {
   N = maxN+1;
   q = malloc(N*sizeof(Item));
   head=0;
   tail=0;
 }

è tutto chiaro nel caso la coda sarà costituita da interi,ma se sono stringhe con quella malloc viene inizializzata una coda che potrà contenere N Item,e cioè N interi,e non N puntatori a int come ci si aspetterebbe

poi non mi è chiaro (nonostante l'abbia scritto io :oops: ) cosa avviene nel main:
   scanf("%s",pezzo);
   printf("Hai inserito in magazzino :%s \n",pezzo);
   el=malloc(strlen(pezzo)+1);
   strcpy(el,pezzo);
   queue_put(el);

...el è un int che assume la dimensione della lunghezza della stringa pezzo(???qual è il senso?),e poi viene copiata una stringa dentro l'intero el(????????si può fare)

Non so se sono chiari i dubbi...spero che mi aiutiate...

Risposte
claudio862
"Mifert4":
in pratica ho capito che si usa il typedef int Item per la riusabilità del codice è perchè comunque in C anche le stringhe sono array di caratteri,e i singoli char sono int limitati nel valore che possono assumere...giusto?

In C le stringhe non esistono. char* è un puntatore a una variabile char. Quindi facendo typedef char* Item; stai dicendo che la tua coda contiene char*, cioè puntatori a char. L'idea è quella di allocare dinamicamente con malloc() dei puntatori a char che verranno poi utilizzati come stringhe nel resto del programma, ma per la coda sono semplicemente puntatori a char (cioè indirizzi di memoria).

Ma non riesco a capire come può funzionare questo programma,cioè ad esempio nella funzione che inizializza la dimensione della coda:
void queue_init(int maxN) {
   N = maxN+1;
   q = malloc(N*sizeof(Item));
   head=0;
   tail=0;
 }

è tutto chiaro nel caso la coda sarà costituita da interi,ma se sono stringhe con quella malloc viene inizializzata una coda che potrà contenere N Item,e cioè N interi,e non N puntatori a int come ci si aspetterebbe

Item == char*, quindi la coda conterrà indirizzi di memoria. Quello che c'è a questi indirizzi di memoria (probabilmente dati che rappresentano stringhe di testo) è trasparente alla coda.

poi non mi è chiaro (nonostante l'abbia scritto io :oops: ) cosa avviene nel main:
   scanf("%s",pezzo);
   printf("Hai inserito in magazzino :%s \n",pezzo);
   el=malloc(strlen(pezzo)+1);
   strcpy(el,pezzo);
   queue_put(el);

...el è un int che assume la dimensione della lunghezza della stringa pezzo(???qual è il senso?),e poi viene copiata una stringa dentro l'intero el(????????si può fare)

Il concetto è giusto: 'pezzo' è un array di char (che può essere usato come puntatore al primo elemento). Tu leggi da tastiera una stringa (= sequenza di caratteri) e la copi dentro 'pezzo'. Se tu inserissi 'pezzo' nella coda staresti memorizzando solamente il suo indirizzo (che è costante per tutta l'esecuzione del 'main()'), quindi all'iterazione successiva lo sovrascriveresti leggendo ancora dalla tastiera. Quello che fai invece è di allocare della memoria con 'malloc()' e copiarci dentro il nome del pezzo, e inserire l'indirizzo della memoria appena allocata nella coda.
Però c'è un errore: 'el' è un int mentre il valore ritornato da 'malloc()' è un puntatore (*void). Non puoi assegnare un puntatore ad un int, perché non è detto che int sia abbastanza grande da contenere void* (anche se spesso è così). Devi quindi dichiarare 'el' come puntatore a char:

int main(int argc, char *argv[])
{
...
    //int el; No, errore
    char * el; // Ok
...

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.