l’identificatore è un nome assegnato dal programmatore – segue regole precise, per es. non inizia mai con un numero, e convenzioni • il valore può anche non essere assegnato – si parla di variabile non inizializzata • il valore può cambiare durante l’esecuzione del programma
l’identificatore è un nome assegnato dal programmatore – segue regole precise, per es. non inizia mai con un numero, e convenzioni • il valore dovrebbe essere assegnato inizialmente • il valore non può cambiare durante l’esecuzione del programma – ma può cambiare in esecuzioni diverse
di parole chiave (keyword) che hanno un preciso significato • le parole chiave non possono essere utilizzate come identificatori di variabili/costanti Anche la nostra lingua ha un lessico: • la parola nave ha un ben preciso significato • la parola jvjnvj non ha alcun significato
di regole che consentono di comporre frasi significative a partire dal lessico • le frasi di un programma si chiamano istruzioni (statement) • i programmi “sgrammaticati” non possono essere eseguiti Anche la nostra lingua ha una sintassi: • “io studio informatica” è una frase sintatticamente corretta • “io studiamo informatica” è una frase sintatticamente errata
un linguaggio • occorre conoscere la semantica delle istruzioni per comprendere che cosa fa un programma – e individuare eventuali errori Anche la nostra lingua ha una semantica ma è ambigua, perché dipende dal contesto • La frase “che bel piatto!” ha almeno due significati – apprezzamento di un piatto di porcellana – apprezzamento di una ricetta
naturali – sono ambigui e devono essere interpretati in base al contesto I linguaggi di programmazione sono formali – le frasi (istruzioni) non sono mai ambigue e hanno un solo significato indipendente dal contesto
valore ad una variabile o costante • Nei linguaggi C like (sintassi simile al C) l’assegnazione ha la seguente sintassi identificatore = valore; • per esempio num = 8; nome = “Mario”; arrivato = false; • la semantica è: prendi il valore a destra dell’uguale e assegnalo alla variabile che si trova a sinistra dell’uguale
costante, è associato a un tipo <identificatore, valore, tipo> • il tipo è l’insieme dei valori che il dato può assumere – intero: solo valori numerici interi – alfanumerico: solo caratteri e simboli speciali – booleano: solo i valori vero (true), falso (false) – carattere: solo caratteri singoli Esistono linguaggi non tipizzati • tipicamente i linguaggi di scripting (PHP, JavaScript,...) – cioè linguaggi le cui istruzioni possono essere inserite nel codice HTML di una pagina web
devono essere dichiarate prima dell’uso – occorre specificare nome e tipo – è possibile assegnare un valore già in fase di dichiarazione • I tipi sono identificati da apposite parole chiave • Per esempio, nei linguaggi C like – int dichiara un intero – double dichiara un razionale – char dichiara un carattere – boolean dichiara un booleano
C like tipo identificatore; • Per esempio int num; double stipendio; char lettera; boolean arrivato; • Semantica: alla variabile identificatore è possibile assegnare solo valori del tipo specificato (o di tipo compatibile)
tutti compatibili fra loro – gli altri tipi non sono tra di loro compatibili e non sono compatibili con i tipi numerici • Per rendere l’idea – posso assegnare ad una variabile di tipo double un valore intero poiché un intero può essere pensato come un numero razionale con uno zero dopo la virgola – non posso assegnare a una variabile di tipo double il carattere “k” poiché numeri e caratteri sono cose diverse • Approfondiremo parlando di promozione e casting
variabile/costante • Dichiarazione e assegnazione possono essere effettuate contemporaneamente, con la sintassi tipo identificatore = valore; • Per esempio int num = 8; double stipendio = 1500.00; char lettera = ‘k’; boolean arrivato = false;
effettuato un controllo di coerenza tra il tipo del valore e il tipo della variabile/costante – int num = 8; è corretto – double stipendio = 8; è corretto, anche se 8 è un valore intero – int num = 2.1589 è errato perché il valore è razionale – char lettera = ‘k’; è corretto – char lettera = ‘1’; è corretto, 1 tra apici rappresenta il carattere 1 – char lettera = “Mario”; è errato perché il valore è una stringa – boolean arrivato = false; è corretto – boolean arrivato = true; è corretto – boolean arrivato = vero è errato perché vero non appartiene al lessico
esempio di promozione (conversione di tipo automatica) – 8 viene trasformato automaticamente in 8.0 e assegnato a stipendio • int num = 10.5; è errato perché 10.5 non è intero, però..... – il programmatore può forzare l’assegnazione effettuando un cast (una conversione di tipo forzata) – basta anteporre al valore il tipo a cui si vuole convertire il valore, tra parentesi tonde int num = (int) 10.5;
può avvenire solo se i tipi sono compatibili • Nel caso precedente int num = (int) 10.5; – il valore 10.5 viene trasformato in intero troncando la parte decimale – il valore effettivamente assegnato a num è pertanto 10 • Con il cast rischiamo di perdere una parte di informazione – passando da 10.5 a 10 abbiamo perso precisione numerica • Questo non costituisce un problema se il programmatore ne è consapevole
disposizione un certo numero di bit in memoria, in base al tipo • Generalmente: – gli interi occupano 32 bit (4 byte) – i double occupano 64 bit (8 byte) – i caratteri occupano da 8 a 16 bit (1 – 2 byte) – i booleani 8 bit (1 byte) – le stringhe occupano un numero di bit variabile in base alla lunghezza • La dichiarazione di tipo consente di riservare in memoria lo spazio necessario per i valori di una variabile/costante
tipo della variabile/costante (segnalando gli errori) • Riserva in memoria lo spazio necessario alla variabile, in base al tipo • Effettua la promozione da un tipo ad uno compatibile ... e fa altre cose...
un programma in linguaggio ad alto livello in un linguaggio comprensibile per una data macchina reale o virtuale – una macchina virtuale è detta interprete • Il codice originale, scritto in linguaggio ad alto livello, si chiama codice sorgente • Il risultato della compilazione e un codice detto codice oggetto • Il codice oggetto è un codice che può essere immediatamente eseguito sulla macchina per la quale è stato generato
• Ogni famiglia di elaboratori ha un suo linguaggio macchina, che dipende dall’hardware • Ne consegue che – per un dato linguaggio ad alto livello esistono (o dovrebbero esistere) tanti compilatori quante sono le famiglie di elaboratori esistenti
un codice comprensibile da una macchina virtuale – una macchina virtuale è detta interprete • Un interprete è un programma che non genera codice intermedio ma – prende un’istruzione alla volta, la traduce nel linguaggio di un’altra macchina e la esegue • Alcuni linguaggi possono essere – solo interpretati (es. PHP) – solo compilati (es. C) – prima compilati e poi interpretati (es. Java)
= espressione; dove espressione è un’espressione aritmetica, di confronto o logica che restituisce un risultato compatibile con il tipo della variabile Esempi di espressioni – espressione aritmetica: 100 + x / z – espressione di confronto: x >= 100 – espressione logica: (x < 10) AND (y != 0) OR (z = x)
operatori predefiniti • Tipici operatori sono: – aritmetici: + - * / % – di confronto: < <= > >== == != – logici (o booleani): && || ! oppure rispettivamente AND OR NOT • Spesso gli operatori predefiniti sono estesi con funzioni di libreria
funzioni di libreria – moduli software aggiunti che consentono di effettuare operazioni complesse semplicemente usando il loro nome ed eventuali parametri • Per esempio – int x = abs(-10); calcola il valore assoluto del parametro – double y = sqrt(25); calcola la radice quadrata del parametro • Le librerie devono essere esplicitamente incluse nel programma, prima di poter usare le loro funzioni, mediante apposite direttive (es. include in C, import in Java)
un ulteriore passaggio prima di poter essere eseguito – occorre collegare le librerie esterne • Il linker (collegatore) è il modulo software che effettua tale operazione, trasformando il codice oggetto in codice eseguibile
dello stesso tipo (omogenei), detto tipo base <variabile, valore1, valore 2, ..., valore N> – per esempio gli array (vettori), gli insiemi (enum, set), le stringhe • di tipo diverso (eterogenei) <(variabile1, valore1di tipo1), ..., (variabileN, valoreN di tipoN)> – per esempio i record
valore2 valore1 • ha un solo nome (a) • ha una dimensione (numero di elementi) che non varia dopo la creazione (3) • ogni elemento occupa una posizione con indice (a partire da 0) • per accedere all’elemento di indice i si scrive a[i] • il tipo array è predefinito nei moderni linguaggi a
• ha un solo nome (s) • ogni carattere occupa una posizione con indice (a partire da 0) • l’accesso al carattere di indice i dipende dal linguaggio – solitamente avviene mediante funzione di libreria • I valori stringa sono rappresentati sempre tra virgolette e, in alcuni linguaggi si possono usare anche gli apici s
valore3 valore2 valore1 • ha un solo nome (r) • è costituito da diversi campi o attributi che possono essere di tipo diverso fra loro • usato solitamente per rappresentare le proprietà di un’entità complessa • per accedere a un campo si scrive r.nomeCampo • si dicono anche “definiti dall’utente” r
cognome di tipo stringa nome di tipo stringa 25 Verdi Lucia • record che rappresenta l’entità studente • ogni istanza ha un suo identificatore • per accedere al nome dell’istanza stud1 si scrive stud1.nome studente schema del record istanze del record stud1 stud2
livello – si distinguono dai linguaggi a basso livello perché non dipendono dall’architettura del sistema di elaborazione – sono solitamente general purpose, cioè adatti per qualsiasi tipo di applicazione anche se... – alcuni linguaggi sono preferibili rispetto ad altri per la realizzazione di applicazioni complesse, grazie alle loro caratteristiche peculiari – per esempio: • Java è particolarmente adatto per lo sviluppo di applicazioni web, di applicazioni per dispositivi mobili e di dispositivi embedded; • C è adatto allo sviluppo di software di base (sistemi operativi)
paradigma – ma può essere usato anche con altri paradigmi Alcuni paradigmi: – imperativo – programmazione strutturata – procedurale – modulare – a oggetti Ogni nuovo paradigma racchiude le caratteristiche positive dei paradigmi precedenti