Vai al contenuto

Chiarimenti su elementi del C


Messaggi raccomandati

Buongiorno a tutti. Sono uno studente universitario al primo anno di ingegneria, e sto studiando per dare informatica, la quale prevede una conoscenza approfondita del C. Il mio libro di testo è una zozzeria: da per scontati la maggior parte dei concetti e non sta nemmeno a fare un esempio quando vengono introdotti nuovi elementi.

 

In particolare mi sono rimasti mooolti dubbi sui dati strutturati (come si referenziano e come si opera con loro) dato che sono spiegati in 2 pagine.

 

Vorrei capire il significato di questa riga di codice e i suoi side effects: 

 

ptr->buffer[count].next=count+1 

 

Scrivo la funzione da cui ho estratto la riga per chiarezza:

 


struct record{
  float value;
  int next;
};

struct list{
  int first;
  int free;
  int size;
  struct record * buffer;
};


void init(struct list * ptr, int size)

{
  int count;
  
  ptr->buffer=(struct record *)malloc(size*sizeof(struct record));
  ptr->size=size;
  ptr->first=ptr->size;
  ptr->free=0;
  for(count=0;count<ptr->size;count++)
    ptr->buffer[count].next=count+1;
} 

 

HELP

MacBook Pro 8,2 13,3" | 8 GB DDR3 1600 MHz; SSD OWC Mercury Pro 6G

Link al commento
Condividi su altri siti

Non preoccuparti! È tutto molto semplice...

 

Una struct è una delle possibili strutture dati in C (ed è forse la più semplice imho). È un modo per raggruppare delle variabili (di solito logicamente raggruppabili).

Ad esempio... un punto nello spazio cartesiano può essere rappresentato come struct:

 

struct Point {
    double x;
    double y;
    double z;
};

 

Questo ti permette nel codice di poter "portarti dietro" un punto, e non una tripletta di double.

Puoi accedere alle variabili di una struct utilizzanto il punto (.). Quindi.. se hai una variabile di tipo Point chiamata 'a', puoi accedere alla 'x' come 'a.x'.

Passo 2: spesso si lavora coi puntatori.. Come si accede allora se hai un puntatore ad una struttura? Beh... sempre col punto ovviamente! Quindi.. 


Point a
Point *b = //some point;

a.x = 5.0;
(*b).y = 6.0;

 

 

Quindi... deferenzi il puntatore => ora hai la struct => usi il punto. 

Ovviamente dato l'uso frequentissimo di questo tipo di accesso si è deciso di creare un nuovo operatore: la freccia.

b->y <=> (*b).y

 

Questa è tutta la teoria che hai bisogno sulle struct. 

Passiamo ora a commentare il tuo codice:

 

Dichiaro una struttura chiamata record che ha due membri/attributi: una variabile float chiamata 'value' e una int chiamata 'next'.

struct record{
  float value;
  int next;
};

 

Dichiaro un'altra struttura dati. Di particolare questa contiene un puntatore ad una struct di tipo record

struct list{
  int first;
  int free;
  int size;
  struct record * buffer;
};

 

 

Ora commento "linea per linea".

void init(struct list * ptr, int size)

{
//nota ptr deve essere già allocato da qualcuno... ad esempio chiamando questa funzione in questo modo:
//struct list myList;
//init(&myList, 10);

  int count;
 
//alloco lo spazio per 'size' oggetti di tipo record e li assegno alla variabile buffer della mia struttura 
  ptr->buffer=(struct record *)malloc(size*sizeof(struct record));
//salvo la size
  ptr->size=size;

//da ora in poi.. non chiediamoci tanto perchè fa una cosa del genere...
//io una lista non l'avrei mai fatta così.

//inizializza le due variabili.
  ptr->first=ptr->size;
  ptr->free=0;

  for(count=0; count< ptr->size; count++)
//come ben sai, un array in C non è altro che il puntatore alla cella iniziale della memoria (che è contigua).
//per indirizzare una particolare cella il metodo più semplice è quello di usare 
//l'operatore [].
//potresti usare anche la deferenziazione diretta del puntatore, ma è più complicato, e di solito si fa in algoritmi complessi....
//ora... la riga qui sotto fa la seguente cosa:
//per ogni elemento "record" della nostra lista (quella che abbiamo allocato con malloc)
//inizializza l'attributo count. E lo inizializza con il count successivo..
    ptr->buffer[count].next=count+1;

//per spiegarti meglio quanto sopra: la nostra lista a parte le variabili accessorie è semplicemente una zona di memoria con "Size" strutture di tipo record
//vedi se capisci dal mio "disegno" qui sotto....
[record0{value=?, next=1}, record1{value=?, next=2}, ..., record_size-1{value=?, next=size}]

}

 

non so se sono stato molto chiaro.. diciamo che come lista fa proprio schifo... ma puoi almeno capire come accedere ai campi delle struct...

Link al commento
Condividi su altri siti

Grazie per la risposta, adesso è chiaro il funzionamento... però ci sono quelle dichiarazioni intrecciate che mi creano confusione.

 

struct record{
  float value;
  int next;
};

struct list{
  int first;
  int free;
  int size;
  struct record * buffer;
};

 

non arrivo a capirne lo scopo pratico, e quel "buffer" che è un puntatore a "struct record", ma che è di tipo "struct list", mi sta facendo impazzire...

Perché è li? Non poteva stare in "struct record"? Non c'è un modo più chiaro per fare quello che deve fare? Non poteva per esempio essere un semplice puntatore a void, tanto viene inizializzato?

MacBook Pro 8,2 13,3" | 8 GB DDR3 1600 MHz; SSD OWC Mercury Pro 6G

Link al commento
Condividi su altri siti

Archiviato

Questa discussione è archiviata e chiusa a future risposte.

×
×
  • Crea Nuovo...