Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
1
Elementi di Informatica
Università degli Studi di Cagliari Corso di Laurea in Ingegneria Elettronica Elementi di Informatica A.A. 2012/2013 Docente: prof. Michele Marchesi DATI E OPERAZIONI
2
Sommario Dati primitivi, vettori, puntatori Record e campi
Memoria statica e dinamica Programmazione procedurale Programmazione modulare Tipi e ADT Programmazione ad oggetti Tipizzazione
3
Dati Primitivi I dati primitivi sono definiti a livello del linguaggio
Ad es., in C essi sono: (unsigned) short, int, long, float, double, char Essi sono poi definiti in concreto a livello del processore Ad es: short = 16 bit, complemento a 2: da a unsigned short = 16 bit, solo positivo da 0 a 65535 int e long = 32 bit, complemento a 2 da a ...
4
Parola di 32 bit allocata in memoria:
Costanti letterali Nei programmi, i dati primitivi possono essere forniti come costanti letterali o essere contenuti in variabili Le costanti letterali sono riconosciute dal compilatore e provocano l’assegnazione in memoria dello spazio corrispondente, e la sua inizializzazione al valore dato var2 = var ; Parola di 32 bit allocata in memoria: 345678
5
1/2 parola di 16 bit allocata in memoria:
Variabili Una variabile deve essere definita dandone il tipo (tipizzazione forte) Il compilatore alloca in memoria una volta per tutte lo spazio per contenere la variabile La variabile è un nome simbolico che denota tale spazio in memoria short var1 = 654; 1/2 parola di 16 bit allocata in memoria: 654 var1
6
I due puntatori occupano lo stesso spazio di memoria
Un puntatore non denota un dato, ma un indirizzo E’ un tipo particolare, che occupa di solito una parola di memoria Il compilatore conosce il tipo di dato puntato short* var2; double* var1; I due puntatori occupano lo stesso spazio di memoria var1 -12 var2
7
9 parole di 32 bit allocate in memoria:
Vettori Un vettore è un insieme di dati, tutti di un certo tipo, contenuti in memoria in un’area contigua ed accessibili dandone l’indice (da 1 a n, o da 0 a n-1) Un vettore è in genere denotato da una variabile Il compilatore alloca in memoria una volta per tutte lo spazio per contenere il vettore, se questo è definito così: int vett[9]; 9 parole di 32 bit allocate in memoria:
8
Record Spesso, sono utili aggregati di dati di tipi diversi
Ad es., un indirizzo ha: via (stringa di max. 40 caratteri) numero (stringa di max. 10 caratteri) CAP (short) Città (stringa di max. 40 caratteri) Provincia (stringa di 2 caratteri) struct indirizzo { char via[40]; char numero [10]; int cap; char citta[40]; char provincia[2];};
9
Record Un record, una volta definito, diventa simile a un tipo del linguaggio Si possono definire variabili, vettori e puntatori del tipo del record Il compilatore alloca lo spazio corrispondente in memoria, sommando quello dei campi del record Un record può contenere campi che sono altri record: struct impiegato { char nome[40]; long matricola; indirizzo indirizzoImpiegato;};
10
Memoria dinamica In alcuni linguaggi (tra cui C e C++) è possibile allocare dinamicamente lo spazio per dei vettori Lo spazio è allocato mentre gira il programma Un puntatore viene assegnato al primo elemento del vettore Tramite di esso, si può poi accedere a tutti gli elementi Quando i dati non servono più, si può deallocare, o liberare, la memoria, che potrà servire di nuovo
11
Memoria dinamica In C si usano le funzioni malloc() e free() :
malloc() ha in input la dimensione (in byte) da allocare, e rende un puntatore al I byte. Allocazione di 10 double, con vett che punta al I° : double* vett; vett = malloc(10 * sizeof(double)); ... free(vett); /* liberazione della memoria */ Lo stesso in C++: vett = new double[10]; delete vett; /* liberazione della memoria */
12
Garbage collection Il dover liberare la memoria dinamica allocata che non serve più è un onere per il programmatore Se si dimentica, la memoria usata cresce indefinitamente, e può far abortire l’esecuzione Se si libera la stessa memoria due volte, si provoca di solito un aborto immediato In alcuni linguaggi, come Java e Smalltalk, è il sistema ad “accorgersi” che una zona di memoria non è più utilizzabile e a liberarla (garbage collection) Non si usano più operatori come free() o delete Ciò ha un certo costo computazionale, ma i vantaggi sono maggiori!
13
Programmazione procedurale
Un programma procedurale (ad es., scritto in C) è composto da dati e da procedure (o funzioni) Le procedure si chiamano a vicenda, e operano sui dati I dati sono primitivi, o vettori, o record. Sono allocati staticamente, o allocati e deallocati dinamicamente Le procedure si scambiano i dati (parametri e valori di ritorno) Esse operano anche su dati globalmente accessibili
14
Programmazione procedurale
funzioni: dati: mem. statica: main() double vett[100]; int dimensione; struct dato{ ... } varDato; ... setup() process() readData() mem. dinamica: commit() openDB() closeDB() readRecord()
15
Programmazione procedurale
16
I problemi della programmazione procedurale
Per grandi sistemi, la complessità dell’approccio è molto elevata I dati comuni creano forti accoppiamenti tra le funzioni Modifiche ai dati possono comportare la modifica a cascata di moltissime procedure, spesso non definibili a priori E’ difficile scomporre grandi sistemi in sottosistemi (moduli) trattabili separatamente
17
Programmazione modulare
Una soluzione proposta da Ada e Modula-2: Mettere insieme dati e procedure che operano su di essi L’insieme di dati e procedure è chiamato modulo o package (in Ada) Un modulo è accessibile tramite le sue procedure pubbliche I dati e le altre procedure del modulo sono privati, e quindi non visibili all’esterno L’insieme delle procedure pubbliche e delle loro definizioni è detto interfaccia del modulo
18
Programmazione modulare
chiamate da altri moduli un modulo software interfaccia procedure pubbliche Un programma modulare è costituito da dati definiti dall'utente, ed usati in modo procedurale. L'accesso ai dati avviene attraverso le interfacce procedure private dati
19
Tipi di dati I tipi primitivi dei linguaggi non sono solo una definizione di dati Essi comportano, in modo implicito, anche la definizione di operazioni sui dati Ad es., il tipo int implicitamente definisce anche le operazioni aritmetiche sui numeri interi, le operazioni di “bit shift”, e molte altre Quando il compilatore deve risolvere un’espressione con interi, applica automaticamente tali operazioni perché conosce il tipo degli operandi
20
Tipi di dati astratti (ADT)
Un tipo primitivo è quindi la definizione sia di un dato che di un insieme di operazioni Questo concetto si può generalizzare Si possono definire nuovi tipi di dato, composti da una struttura dati (un record) e da operazioni per operare su tale struttura dati Tali tipi si denotano come tipi di dati astratti (ADT) Un ADT incapsula la sua struttura dati e fornisce un’interfaccia per accedervi E’ un altro modo per considerare un modulo
21
Un ADT ADT: tipo double del C
Struttura dati: 2 parole di memoria (64 bit), col numero in formato IEEE Interfaccia: Operazioni aritmetiche double: +, -, *, / Funzioni matematiche double: sin(double), exp(double), abs(double)… Operazioni di conversione verso altri formati … Questo ADT è fornito dal linguaggio, e usato dai programmatori in maniera trasparente
22
Un altro ADT Tipo: Pila (stack) di int
Una pila di interi è una struttura dati che permette di inserire e togliere numeri interi Il primo che esce è l’ultimo entrato (LIFO) Interfaccia: void push(int, Pila) inserisce nella pila il numero dato int pop(Pila) toglie dalla pila il numero intero in testa e lo rende int head(Pila) rende il numero in testa alla pila senza toglierlo int size(Pila) rende il numero di elementi della pila Quando è creata, una Pila è vuota pop() o head() su pila vuota dà errore
23
La Pila Posso definire variabili di tipo Pila, e usarle:
Pila miaPila; push(10, miaPila); push(20, miaPila); int datoLettoDaPila = pop(miaPila); ... Si noti che non ho definito esplicitamente la struttura dati della Pila, ma solo la sua interfaccia Posso implementare una Pila in molti modi, sia come struttura dati che come codice delle sue operazioni
24
Implementazione di una Pila
Definisco la struttura dati della Pila. Ad es: struct Pila { int* vettoreDati; int numeroElementi; int dimensioneVettoreDati; }; Scrivo di conseguenza il codice delle funzioni che operano su una Pila “Impacchetto” tutto in un file, che diventa un modulo
25
Oggetti Nell’esempio dell’implementazione della Pila, ho definito una struttura dati capace di contenere gli elementi della Pila L’uso della Pila è però fatto tramite funzioni Tali funzioni hanno la Pila tra i propri argomenti Questo è il massimo che si può fare col C Nei linguaggi ad oggetti si può fare di più: Si definiscono insieme dati e operazioni (metodi) Si chiamano i metodi direttamente sul dato
26
La Pila in C++ class Pila { int* vettoreDati; int numeroElementi;
int dimensioneVettoreDati; public: void push(int); int pop(); int size(); }; Pila miaPila; miaPila.push(10); miaPila.push(20); int datoLettoDaPila = miaPila.pop(); In C: struct Pila { int* vettoreDati; int numeroElementi; int dimensioneVettoreDati; }; Pila miaPila; push(10, miaPila); push(20, miaPila); int datoLettoDaPila = pop(miaPila);
27
POO: i tre concetti fondamentali
Oggetto, Messaggio e Classe Un oggetto è un "impacchettamento" di dati e procedure (metodi) per operare sui dati I dati sono chiamati anche variabili d'istanza o variabili membro) Gli oggetti sono moduli software ideali perché si possono definire e far evolvere indipendentemente
28
Messaggi Gli oggetti interagiscono inviandosi reciprocamente dei messaggi Un messaggio è la classica chiamata di funzione, con la differenza che il metodo chiamato si riferisce sempre ad un oggetto preciso (il ricevente) Un messaggio è composto dal nome dell'oggetto cui è inviato (il ricevente), dal nome del metodo eseguito (il selettore) e dagli eventuali parametri unImpiegato.incrementaStipendio(12.0); double stip = unImpiegato.leggiStipendio(); pila.push(33);
29
Classi e istanze Una classe è la descrizione di un gruppo di oggetti simili, con le stesse variabili e gli stessi metodi La classe definisce i dati e fornisce il codice dei metodi degli oggetti che descrive, detti le sue istanze La classe è una descrizione, e quindi appartiene al codice sorgente del programma Le sue istanze esistono nella memoria del calcolatore durante l'esecuzione del programma I metodi pubblici di una classe ne costituiscono l’interfaccia
30
Ereditarietà Capita spesso la necessità di descrivere oggetti solo un poco diversi da oggetti già descritti L'ereditarietà consente di specificare solo le differenze di una classe (sottoclasse) rispetto ad una classe base (superclasse) Dati e metodi sono ereditati, nuovi dati e metodi possono essere aggiunti, e metodi possono essere ridefiniti
31
Binding dinamico Binding: specifica di tutte le informazioni di una chiamata a funzione (nome, numero e tipo dei parametri, locazione) Il binding può essere: Statico, cioè eseguito durante la compilazione e il "loading": non si può cambiare durante l'esecuzione. Dinamico, cioè eseguito durante l'esecuzione stessa del programma. Quando un oggetto riceve un messaggio, è solo a “runtime” che il sistema verifica a che classe appartiene, e quindi che metodo eseguire Il binding dinamico permette di eliminare le istruzioni “switch” dai programmi
32
Programmazione ad oggetti
Gli oggetti modellano entro il calcolatore il “mondo esterno” I sistemi sono più comprensibili e più naturalmente progettabili e modificabili Ogni oggetto incapsula i propri dati, e quindi facilita le modifiche al programma Un programma ad oggetti è composto da molti oggetti che si scambiamo messaggi I linguaggi ad oggetti: Java, C++, C#, Smalltalk, Python, Ruby
33
Un programma ad oggetti
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.