Elementi di Informatica

Slides:



Advertisements
Presentazioni simili
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Advertisements

1 Il linguaggio C Precisazioni sull’esperienza in laboratorio.
IL PROCESSORE I MICROPROCESSORI INTEL Il microprocessore è un circuito integrato dotato di una struttura circuitale in grado di effettuare un determinato.
Fondamenti di Informatica - D. Talia - UNICAL 1 Fondamenti di Informatica FONDAMENTI DI INFORMATICA Domenico Talia
1 Elementi DI INFORMATICA Università degli Studi di Cagliari Corso di Laurea in Ingegneria Elettronica Linguaggio C A.A. 2011/2012
Fondamenti di Informatica A - Massimo Bertozzi I PUNTATORI.
1 ELEMENTI DI INFORMATICA Università degli Studi di Cagliari Corso di Laurea in Ingegneria Elettronica Linguaggio C A.A. 2011/2012
Programmazione in Java Parte I: Fondamenti Lezione 1 Dott. Marco Faella.
Fondamenti di Informatica A - Massimo Bertozzi LE RAPPRESENTAZIONI CONCATENATE.
.  I tipi di dati non primitivi sono gli array, le struct e le union.  Gli array sono degli aggregati di variabili dello stesso tipo.  La dichiarazione.
Fondamenti di Informatica - D. Talia - UNICAL 1 Fondamenti di Informatica PROBLEMI E ALGORITMI LINGUAGGIO MACCHINA.
Ereditarietà Uno dei principi della programmazione orientata agli oggetti (OOP) è il riuso Le classi dovrebbero essere progettate come componenti riutilizzabili.
Rileaborato da M. Lenzerini - Basi di dati
© 2007 SEI-Società Editrice Internazionale, Apogeo
Sistemi e Applicazioni per l’Amministrazione Digitale
Java World Introduzione.
ODMG.
Universita’ di Milano Bicocca Corso di Basi di dati 1 in eLearning
Java: concetti e costrutti base
Introduzione al linguaggio C
Dal problema al processo risolutivo
Il linguaggio C Strutture Moreno Marzolla
7. Strutture di controllo Ing. Simona Colucci
Dal problema al processo risolutivo
10. Programmazione Ricorsiva Ing. Simona Colucci
Programmazione a oggetti
Unità didattica 1: Introduzione al linguaggio Java
L’AMBIENTE CODE BLOCKS E L’IO
TIPI PRIMITIVI TIPI STRUTTURATI
JAVA usa una rappresentazione in VIRGOLA MOBILE
Tipo di dato: array Un array è un tipo di dato usato per memorizzare una collezione di variabili dello stesso tipo. Per memorizzare una collezione di 7.
Informatica per l’Ingegneria
Corso Java Introduzione.
Vettori dinamici Definiremo la classe vector.
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Controllo e microprogrammazione
Programmazione e Laboratorio di Programmazione
OBJECT ORIENTED DATABASE
Programmare.
Esercitazioni di C++ 31 dicembre 2018 Claudio Rocchini IGMI.
Programmazione e Laboratorio di Programmazione
Copia di oggetti il costruttore di copia ha le stesse particolarità della signature di un costruttore ordinario; il primo parametro è una reference ad.
Introduzione agli Algoritmi e alle Strutture Dati
Corso di Laurea Ingegneria Informatica Fondamenti di Informatica
© 2007 SEI-Società Editrice Internazionale, Apogeo
Definizione di linguaggio di programmazione
APPUNTI SUL LINGUAGGIO C
APPUNTI SUL LINGUAGGIO C
Corso di Laurea Ingegneria Informatica Fondamenti di Informatica
APPUNTI SUL LINGUAGGIO C Esercizi su File e Alberi Binari
Lucidi della Pof.ssa Pazienza
APPUNTI SUL LINGUAGGIO C
APPUNTI SUL LINGUAGGIO C
APPUNTI SUL LINGUAGGIO C Allocazione dinamica della memoria
Programmazione e Laboratorio di Programmazione
APPUNTI SUL LINGUAGGIO C
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Java Introduzione.
Programmazione e Laboratorio di Programmazione
UML Diagramma statico di una classe
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Array e Stringhe Linguaggio C.
Programmazione e Laboratorio di Programmazione
Ese 3 (del 3 Aprile 2003).
Transcript della presentazione:

Elementi di Informatica Università degli Studi di Cagliari Corso di Laurea in Ingegneria Elettronica Elementi di Informatica http://agile.diee.unica.it A.A. 2012/2013 Docente: prof. Michele Marchesi DATI E OPERAZIONI

Sommario Dati primitivi, vettori, puntatori Record e campi Memoria statica e dinamica Programmazione procedurale Programmazione modulare Tipi e ADT Programmazione ad oggetti Tipizzazione

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 - 32768 a +32767 unsigned short = 16 bit, solo positivo da 0 a 65535 int e long = 32 bit, complemento a 2 da -2147483648 a 2147483647 ...

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 = var1 + 345678; Parola di 32 bit allocata in memoria: 345678

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

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; 12345.67898765 I due puntatori occupano lo stesso spazio di memoria var1 -12 var2

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:

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];};

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;};

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

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 */

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!

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

Programmazione procedurale funzioni: dati: mem. statica: main() double vett[100]; int dimensione; struct dato{ ... } varDato; ... setup() process() readData() mem. dinamica: commit() openDB() closeDB() readRecord()

Programmazione procedurale

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Un programma ad oggetti