Supporta il tuo Forum su Patreon!
 
  > Register  
  > Calendar  
  > Members List  
 
  > Supporta il Forum  
  > Today's Posts  
   

Go Back   netgamers.it > Tech & Tech > Developer's Zone

Reply
 
Thread Tools Rate Thread
Old 14th January 2011, 15:40   #1
Arėsius
Soft computer
 
Arėsius's Avatar
 
Join Date: Feb 2000
Posts: 67,581
[Impariamo il C] Lezione 13

Buongiorno e buon anno.

Nelle puntate precedenti del corso collaborativo di programmazione:
  1. installazione dell'IDE, cenni di architettura degli elaboratori
  2. sintassi del C, programmazione strutturata
  3. ancora sulla sintassi, i tipi di dato, le variabili
  4. variabili parte seconda: gli array
  5. introduzione delle funzioni
  6. operatori aritmetici e logici
  7. costrutti di selezione
  8. costrutti di iterazione
  9. ancora sull'iterazione
  10. array multipli e struct
  11. ricorsione
  12. ancora ricorsione, memoria (record attivazione, heap, stack, ecc), introduzione dei puntatori
In questo capitolo:
  • liste e allocazione di memoria

Liste e allocazione memoria

Nella precedente lezione abbiamo visto ciņ che rende il C diverso da tutti gli altri linguaggi di programmazione: la gestione della memoria a basso livello.

Con il C possiamo andare a ravanare nelle singole celle di memoria a nostro piacimento, anche sbirciando laddove non dovremmo. Questa cosa (e anche altre che vedremo in seguito quando studieremo l'allocazione) č ciņ che diversifica i linguaggi cosidetti managed (Java, C#, ecc) da quelli che non lo sono.

Nella lezione precedente, uno degli esercizi consisteva nel creare una struttura fatta di due campi: un valore numerico e un puntatore alla struttura.

Questo tipo di struttura č chiamata lista:



Code:
struct Lista {
  int inf;
  struct Lista* pun;
};
Nell'esempio di sopra, avremo che

Code:
struct Lista prima;
prima.inf= 3;
prima.pun = NULL;
Il valore NULL č un modo con cui possiamo dire che la nostra Lista si arresta in quella cella. Sģ, perché la cosa bella delle liste č che possiamo aggiungere tutti i valori che vogliamo concatenando altri pezzi di lista.

Code:
struct Lista prima;
struct Lista seconda;
struct Lista terza;

prima.inf = 5;
prima.pun = &seconda;

seconda.inf = 20;
seconda.pun = &terza;

terza.inf = 12;
terza.pun = NULL;


Quando creiamo una lista, ci conserviamo anche due informazioni. La prima č il puntatore alla posizione in cui ci troviamo.

Code:
struct Lista* posizione;
Questo perché noi utilizziamo i puntatori di ogni cella per trovare la posizione successiva in memoria. Non possiamo fare cose tipo Lista[2] per ottenere direttamente il terzo valore (cioé 12), dobbiamo partire dalla testa e fare due saltini. Ecco quindi la seconda informazione che ci serve: in che punto della memoria ha inizio la nostra lista!!

Code:
struct Lista* testa;
Quindi, per leggere il dato alla seconda posizione, potremmo fare

Code:
struct Lista* testa = &prima; // dove iniziamo
struct Lista* posizione = testa;  // dove ci troviamo

posizione = posizione->pun;  // primo salto
posizione = posizione->pun;  // secondo salto

int dato = posizione->inf;
Analizziamo il codice. Prima di tutto ci prendiamo le posizioni in memoria del primo elemento. Una la immagazziniamo in "testa" e la teniamo per riferirci all'inizio della lista. L'altra (posizione) la useremo per spostarci nella lista.

Nelle prime due righe in grassetto utilizziamo i puntatori alla celle successive per aggiornare "posizione".

Infine, deferenziamo il puntatore e "acchiappiamo" il campo della struttura "inf". Questa manovra č un po' perversa e quindi ha richiesto l'introduzione di un nuovo operatore (chiamato "di accesso ai campi"). L'alternativa sarebbe stata scrivere una cosa tipo

Code:
int dato = (*posizione).inf;   // orrore!
che puņ diventare immediatamente un macello da leggere, anche perché l'asterisco č anche l'operatore di moltiplicazione.

Dunque, le liste sono pił intelligenti degli array, perché non abbiamo bisogno di conoscere in anticipo la dimensione da allocare. Tuttavia, avrete notato, per come abbiamo scritto il codice prima, questa informazione ci serve comunque (perché abbiamo dovuto dichiarare una nuova variabile per ogni nuova cella).

A noi non piace.

Ecco dunque sorgere la necessitą di poter realizzare nuovi pezzi di lista in maniera arbitraria, on demand diciamo. Facciamo un esempio (stupido, ma per capirci meglio). Mettiamo di avere un array

Code:
int a[10]={1,2,3,4,5,6,7,8,9,10);
Vogliamo partire dall'array e creare una lista. Come possiamo fare? In pseudocodice č cosģ:

Code:
primo_elemento = crea_nuovo_elemento_lista()
primo_elemento.valore = a[0]
primo_elemento.next = NULL

posizione_nella_lista = &primo_elemento

for( i=1; i<10; i++ ) {
  
  nuovo_elemento = crea_nuovo_elemento_lista()
  
  // questa posizione si riferisce all'elemento precedente,
  // che aggiorniamo collegando il nuovo elemento
  posizione_nella_lista->next = &nuovo_elemento

  nuovo_elemento.valore = a[i]
  nuovo_elemento.next = NULL;
  posizione_nella_lista = &nuovo_elemento;

}
Le parti in grassetto sono quelle che non sappiamo ancora fare. O meglio, le sappiamo fare in maniera statica come visto prima: dichiarando variabili su variabili. Il C ci consente invece una maniera pił elegante di procedere:

Code:
struct Lista* nuovo_elemento = (struct Lista*) malloc ( sizeof( struct Lista ) );
Spendiamo qualche riga per analizzare questa istruzione. Analizziamola da sinistra a destra. Prima di tutto stiamo dicendo che "nuovo_elemento" č una variabile di tipo "puntatore a struttura lista". Nulla di nuovo.

Assegniamo poi questa variabile a quella roba che sta alla destra dell'uguale. Il primo pezzo, quello tra parentesi, č un cast. I cast - qualcuno l'ha gią visto nelle lezioni precedenti - forzano la conversione di tipo.

Poiché i cast li vedremo pił avanti e, in particolare, questo cast č inutile ma va messo ugualmente per compatibilitą, ignoratelo. Sappiate solo che dev'essere esattamente dello stesso tipo del puntatore a sinistra.

Proseguiamo e vediamo apparire la paroletta magica malloc che sta per memory allocation (orly?). Ricordate la divisione della memoria in stack e heap? ecco, la malloc č quella che ci consente di utilizzare lo heap, piazzandoci dentro tutte le strutture e i dati che vogliamo!

La malloc č una funzione, e quindi ha dei parametri. Ne ha uno, che č la dimensione in bytes della memoria da allocare. Come facciamo a sapere quanta memoria ci serve? Ecco venire in aiuto l'ultima funzione di quella riga, cioé sizeof che, dato in ingresso un tipo di dato, in questo caso "struct Lista", ci dice quanta memoria occupa.

Dunque, ricapitolando, quell'istruzione dice: ragazzo, voglio che mi crei un elemento della lista nello heap e piazza il suo indirizzo in questa variabile.


Esercizio 1: realizzate un programma che legga un numero qualsiasi di caratteri da tastiera, salvandoli in una lista. Poi, all'inserimento di un punto esclamativo, stampa i caratteri numerici della lista

Esercizio 2 (difficile): come realizzereste la cancellazione di un elemento da una lista?

Esercizio 3 (difficile, teorico): fate

Code:
printf("%d\n", sizeof( struct Lista ));
e cercate di spiegare perché vi da quella cifra.
__________________
Lode a Bacco, in saecula saeculorum.
Emergent

Last edited by Arėsius; 14th January 2011 at 15:45.
Arėsius is online now   Reply With Quote
Old 15th January 2011, 00:07   #2
.Z.
fork()
 
.Z.'s Avatar
 
Join Date: Jan 2002
Location: Bologna
Posts: 13,461
precisazione pił o meno utile: sizeof ha la sintassi di una funzione, ma č un operatore.
__________________
And for any day that stings, two better days it brings.
Nothing is as bad as it seems.
.Z. is offline   Reply With Quote
Old 15th January 2011, 00:21   #3
Arėsius
Soft computer
 
Arėsius's Avatar
 
Join Date: Feb 2000
Posts: 67,581
wow figo, lo scopro ora

quindi sarebbe sizeof struct Lista volendo, non servono le parentesi cazzofigata
__________________
Lode a Bacco, in saecula saeculorum.
Emergent
Arėsius is online now   Reply With Quote
Old 15th January 2011, 15:52   #4
.Z.
fork()
 
.Z.'s Avatar
 
Join Date: Jan 2002
Location: Bologna
Posts: 13,461
Le parentesi non saprei , ma puoi sapere a tempo di compilazione quanti elementi ha un array statico risparmiandoti una variabile o una define, che dovresti tenere aggiorate se cambia la dimensione dell'array.

Es. a riga 12:

Code:
     1 #include<stdio.h>
     2	#include<stdlib.h>
     3	
     4	
     5	int
     6	main (int argc, char *argv[])
     7	{
     8	    int i,
     9	        array[] = { 1, 2, 3, 4, 5},
    10	        sum = 0;
    11	
    12	    for (i = 0; i < sizeof(array) / sizeof(array[0]); i++) {
    13	        sum = sum + array[i];
    14	    }
    15	
    16	    printf("%d\n", sum);
    17	
    18	    return EXIT_SUCCESS;
Con una macro scrivi solo LEN(array) e diventa un po' pił snello
__________________
And for any day that stings, two better days it brings.
Nothing is as bad as it seems.
.Z. is offline   Reply With Quote
Old 16th January 2011, 16:14   #5
uizz
Registered User
 
uizz's Avatar
 
Join Date: Jan 2010
Posts: 513
Ops ho visto adesso la lezione nuova, appena ho tempo mi metto all'opera
uizz is offline   Reply With Quote
Old 16th January 2011, 23:13   #6
Arėsius
Soft computer
 
Arėsius's Avatar
 
Join Date: Feb 2000
Posts: 67,581
ho scoperto che anche la virgola č un operatore; la mia vita č cambiata
__________________
Lode a Bacco, in saecula saeculorum.
Emergent
Arėsius is online now   Reply With Quote
Old 17th January 2011, 00:33   #7
.Z.
fork()
 
.Z.'s Avatar
 
Join Date: Jan 2002
Location: Bologna
Posts: 13,461
ma come, mai scritti for senza corpo?

Code:
int i, sum;

for (sum = 0, i = 0;
     i < 100;
     sum += i, i++);
__________________
And for any day that stings, two better days it brings.
Nothing is as bad as it seems.
.Z. is offline   Reply With Quote
Old 17th January 2011, 00:41   #8
uizz
Registered User
 
uizz's Avatar
 
Join Date: Jan 2010
Posts: 513
Bella la lezione, prossimamente gli esercizi...e interessante la questione sugli operatori...pare proprio che sizeof sia un operatore unario e non abbia bisogno di parentesi quando applicato a una variabile

edit:
Quote:
Originally Posted by .Z. View Post
for senza corpo
:-O

Last edited by uizz; 17th January 2011 at 00:51.
uizz is offline   Reply With Quote
Old 17th January 2011, 17:25   #9
Arėsius
Soft computer
 
Arėsius's Avatar
 
Join Date: Feb 2000
Posts: 67,581
ma sei rimasto solo tu uizz?
__________________
Lode a Bacco, in saecula saeculorum.
Emergent
Arėsius is online now   Reply With Quote
Old 17th January 2011, 18:10   #10
uizz
Registered User
 
uizz's Avatar
 
Join Date: Jan 2010
Posts: 513
č sempre cosģ forever alone

no, comunque, ho provato a fare l'es1 in un momento libero al lavoro ma mi č risultato un po' pił complicato del previsto...in pił ho dimenticato le ultime lezioni devo mettermici con calma a casa, magari stasera
uizz is offline   Reply With Quote
Old 17th January 2011, 18:14   #11
Arėsius
Soft computer
 
Arėsius's Avatar
 
Join Date: Feb 2000
Posts: 67,581
puņ tranquillamente essere che io abbia dato per scontato qualcosa, che non lo č affatto. se hai domande ponile pure!
__________________
Lode a Bacco, in saecula saeculorum.
Emergent
Arėsius is online now   Reply With Quote
Old 17th January 2011, 21:34   #12
Pier4R
Ex falso quodlibet
 
Pier4R's Avatar
 
Join Date: Jul 2004
Location: equgpbc.r2.Frisia
Posts: 18,665
intanto mi iscrivo, sorry are ma sto nerdando duro. Comunque non scordarti che con la nanopazzowiki e l'indicizzazione di ngi prima o poi arriveranno frotte di cristi. (io ho gią linkato la wiki ad alcuni ragazzi del corso di c)
__________________
Ngi the e.FlameeXperience • • • .Fe • • • ! • • • ngi.agorą@twitter (sottoscrivi per essere incluso)
You must play online: warSow • • • EnemyTerritory + etpro • • • quake 4 + q4max & quake 3 + cpma & quakelive • • • Teeworlds! • • • hoi2series

Ringrazio i grammar nazi che mi fanno comprendere gli errori ; my.IL
; lettere porno

Last edited by Pier4R; 17th January 2011 at 21:39.
Pier4R is offline   Reply With Quote
Old 17th January 2011, 23:06   #13
nanomad
Dietro le sbarre
 
nanomad's Avatar
 
Join Date: Apr 2005
Location: Papia (olim Ticinum)
Posts: 5,221
Nanopazzo

Devo caricare la 13 , ma sono io quello carico di lavoro in questo momento

Problema rientrato
__________________
Rivuoi i video nel forum? Usa questa estensione (chrome)
Source & firefox version
"(...) the three great virtues of a programmer: laziness, impatience, and hubris." -- LarryWall

Last edited by nanomad; 18th January 2011 at 18:54.
nanomad is offline   Reply With Quote
Old 18th January 2011, 00:49   #14
Arėsius
Soft computer
 
Arėsius's Avatar
 
Join Date: Feb 2000
Posts: 67,581
tanti visitatori, tanto smerdamento mi rovinerņ la reputazione
__________________
Lode a Bacco, in saecula saeculorum.
Emergent
Arėsius is online now   Reply With Quote
Old 18th January 2011, 10:06   #15
Niymiae
Five Leaf Clover
 
Niymiae's Avatar
 
Join Date: Mar 1999
Location: Magrathea
Posts: 3,580
Are che dici, provo a fare una piccola intro al progetto e vediamo se c'č interessamento?
__________________
the e.UGO Xperience
The HyperIntelligent Shade of the color Green™
Who the hell do you think I am?
Steveholt <The Oscure> @ Pozzo dell'Eternitą

••
Niymiae is online now   Reply With Quote
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 21:24.


Copyright 2017-2024 by netgamers.it