Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
03 - VariabiliMemoria PDF
03 - VariabiliMemoria PDF
Variabili e memoria
Operatori ed espressioni
Fondamenti di Programmazione
CdL Ingegneria Informatica e dell'Informazione
Lezione 3
Le origini del C
Sviluppato a partire dal
linguaggio B ideato da
Thompson per creare
versioni iniziali di Unix
Implementato all’inizio degli anni ’70 da D.
Ritchie presso i laboratori Bell
E' diventato uno standard ANSI (American
National Standard Institute) nel 1989 (terminato
nel 1990)
Aggiornato nel 1999 (C99)
Caratteristiche del linguaggio C
È un linguaggio di programmazione general purpose,
imperativo a blocchi, procedurale
È considerato un linguaggio di alto livello ma non
troppo
– fornisce un insieme ristretto di costrutti di
controllo e di parole chiave, ma un insieme
ricco di operatori e strutture dati avanzate
Lo standard definisce librerie
specificano funzioni (.h) per l’accesso al sistema
operativo, l’allocazione di memoria, il trattamento
delle stringhe, funzioni matematiche...
Motivazioni
Perchè usare il C?
Offre al programmatore potenza, efficienza, portabilità
Visione a basso livello delle risorse
• Memoria e dispositivi
• Possibilità di incapsulare codice assembler
Capacità di manipolare i singoli bit
Uso efficiente delle risorse
• Ridotto uso di memoria
• Compilazione efficiente
Caratteristiche fondamentali
Il lessico
Istruzioni di base, strutture di controllo e blocchi
Le variabili e i tipi primitivi
Gli operatori e le espressioni
Problem solving
Il lessico
Alfabeto:
utilizzato per scrivere i programmi UNICODE
Parole chiave:
parole riservate che hanno un significato particolare
e non possono essere ridefinite
Parole chiave definite dallo standard ANSI
auto • double
int
struct
break • else
long
switch
case • enum
registe
typedef
char • extern r
union
const • float
return
unsigned
continue • for
short
void
default • goto
signed
volatile
do • if
sizeof
while
static
Il lessico
Identificatori:
nomi usati per indicare variabili, funzioni etc.
Separatori:
caratteri che permettorno di separare o raggruppare
parti di codice: ( ) { } [ ] ; , .
Operatori:
denotano operazioni
Letterali:
sequenze di caratteri per rappresentari valori di tipi
primitivi : 1234 “questa è una stringa”
Il lessico
Commenti:
Programmare bene significa anche saper
scrivere codice ben commentato e leggibile
num_student
Caratteri vietati:
. , ; : + - = \/ * < > ! ? @ # % $ ^ & ' ~ parentesi e spazi
Sommario
Caratteristiche fondamentali
Il lessico
Istruzioni di base, strutture di controllo e
blocchi
Le variabili e i tipi primitivi
Gli operatori e le espressioni
Problem solving
Struttura di un programma
<istruzione>;
{<istruzione>; <istruzione>;}
scrivere istruzioni chiare, una per riga
evidenziare blocchi di istruzioni con le
parentesi graffe anche se consistente di un
solo comando
utilizzare l’indentazione dei diversi blocchi
del programma per una più facile lettura del
codice stesso.
Moduli
I programmi sono spesso abbastanza complessi da
dover essere scomposti in “pezzi” più maneggevoli
Un modulo consiste di istruzioni per svolgere un
certo compito raggruppate insieme in un’unità a cui è
dato un nome
il nome può essere usato come sostituto dell’intero insieme di
istruzioni
Vantaggi:
risparmio di scrittura, organizzazione, riutilizzo
Creare un programma
eseguibile
Editor
Scrittura del programma sorgente
(nome_file.c)
Compilatore
Produce codice oggetto scritto in linguaggio
assembler (nome_file.obj)
Linker
Collega tra loro i moduli che costituiscono il
programma (files oggetto) e produce il
codice eseguibile (nome_file.exe)
Loader (fase di caricamento)
L'inizio del programma
main (non Main o MAIN) è una funzione speciale che
indica l’inizio dell’esecuzione del programma e deve
pertanto essere presente in ogni programma.
Le parentesi vuote dopo main significano che la funzione
non prende nessun parametro in input.
main()
{
…
}
Sommario
Caratteristiche fondamentali
Il lessico
Istruzioni di base, strutture di controllo e blocchi
Le variabili e i tipi primitivi
Gli operatori e le espressioni
Problem solving
Variabili e tipi
Variabile: locazione di memoria a cui è dato un
nome con cui chiamarla ed utilizzarla (contenitore di
dati)
programmatore usa il nome senza necessariamente
sapere che esso faccia riferimento ad una locazione di
memoria
Tipo: ogni variabile ha un tipo che indica che genere
di dati la variabile può contenere
una variabile può contenere dati di tipo intero (ad es., 15
o 2038), oppure dati di tipo carattere (ad es., ‘a’ o ‘£’)
Le dimensioni delle variabili numeriche dipendono
dall’architettura dell’elaboratore sottostante
Classe di memoria: determina la durata di vita
della variabile.
Creazione di variabili
Tutte le variabili devono essere dichiarate prima di poterle
utilizzare
Una dichiarazione di variabile associa un nome alle locazioni
di memoria ad essa corrispondenti e specifica il tipo di dati che
la variabile conterrà:
Per esempio, per creare tre variabili che memorizzino il numero
di cesti, il numero di uova per cesto ed il numero totale di uova:
int total;
total=0;
Oppure
int total=0;
Definizione: dichiarazione con inizializzazione
il compilatore non segnala errore se si inizializza
una variable con un valore fuori range
Nomi significativi
Tipo Descrizione
Tipo
Bit occupati • Intervallo
• char 8 0 – 255
• int 16 -32768 – 32767
• float 32 3.4E-38 – 3.4E+38
• double 64 1.7E-308 – 1.7E+308
• void 0 indefinito
x=±1.a1....am × 2E
Segno della
Mantissa (s)
0 00000000 00000000000000000000000
Segno della
Mantissa
0 10000010 10101000000000000000000
Esponente Mantissa
1*2-1+1*2-3+1*2-5 =0.5+0.125+0.03125
=0.65625
3
Segno della
Mantissa
0 10000010 10101000000000000000000
Underflow e overflow:
– Tentativo di rappresentare un numero fuori dal range di
valori possibili
Errore di cancellazione:
– a+b vale a, se a>>b
Costanti
Una costante è una locazione di memoria di
un dato
Il valore immagazzinato non può variare
durante l’esecuzione di un programma
a = 2;
b = 3.5; 0xffffa001 00000010
c = 2.; 0xffffa002 ????????
a = 2;
b = 3.5; 0xffffa001 00000010
c = 2.; 0xffffa002 01000000
a = 2;
b = 3.5; 0xffffa001 00000010
c = 2.; 0xffffa002 01000000
a = 2; 0xffffa000 01100110
b = 3.5; 0xffffa001 00000010
c = 2.; 0xffffa002 01000000
f ↔ 102 (6616) 0xffffa003 01100000
0xffffa004 00000000
0xffffa005 00000000
0xffffa006 01000000
0xffffa007 00000000
0xffffa008 00000000
0xffffa009 00000000
Modificatori di tipo
I tipi di dato primitivi possono essere estesi
con l’uso di alcuni modificatori:
Di dimensione: short, long
Di “valutazione”: unsigned
Esempio:
long int l;
unsigned int i;
Tipi di dato scalare
Tipo Byte Range
int 4 da 231 a 2311
short 2 da 215 a 2151
long 4 da 231 a 2311
Numeri
interi
8 da 263 a 2631
unsigned int 4 da 0 a 2321
unsigned short 2 da 0 a 2161
unsigned long 8 da 0 a 2641
Carattere
(è rappresentato char 1 da 27 a 271
con un numero
intero!!!)
unsigned char 1 da 0 a 281
Numeri
float 4 7 cifre decimali
reali double 8 16 cifre decimali
enum 4 /
puntatore* 4 da 231 a 2311
8 da 263 a 2631
Sommario
Caratteristiche fondamentali
Il lessico
Istruzioni di base, strutture di controllo e blocchi
Le variabili e i tipi primitivi
Gli operatori e le espressioni
Problem solving
Operatori
Un operatore è un simbolo che istruisce C
di eseguire una operazione su uno o più
operandi.
Esistono tre classi di operatori:
aritmetici (o matematici)
logici e relazionali
bit a bit.
Espressioni
int a=2,b;
float c=3.5,d;
b=a+c;
d=c/a;
Quanto vale a+c? Quanto vale b? Quanto vale d?
Conversione di tipo
a = 2; a = 2;
b = ++a; a=a+1;
b = a;
a = 2;
b = a++; a = 2;
b = a;
a=a+1;
Operatori - Priorità
Caratteristiche fondamentali
Il lessico
Istruzioni di base, strutture di controllo e blocchi
Le variabili e i tipi primitivi
Gli operatori e le espressioni
Problem solving
Problema: conversione di gradi
Fahrenheit in Celsius
Dobbiamo studiare le diverse temperature rilevate in
periodi diversi alcune delle quali sono espresse in
Fahrenheit, mentre altre in Celsius. Vorremmo avere
tutte le temperature in gradi Celsius.
Analisi: Conversione da gradi Fahrenheit a Celsius
Dati in ingresso: temperatura in Fahrenheit (tf)
Risultato: temperatura in Celsius (tc)
Formula: tc=(tf-32)x5/9
Algoritmo (da raffinare):
“Acquisisci” i dati
Calcola la conversione
“Visualizza” il risultato
Programmi e variabili
main() {
float tc, tf = 90., conv;
float offset = 32.;
conv = 5./9.;
tc = (tf – offset) * conv;
}
? 90. ?
tc tf conv
Programmi e variabili
main() {
float tc, tf = 90., conv;
float offset = 32.;
conv = 5./9.;
tc = (tf – offset) * conv;
}
? 90. ? 32.
tc tf conv offset
Programmi e variabili
main() {
float tc, tf = 90., conv;
float offset = 32.;
conv = 5./9.;
tc = (tf – offset) * conv;
}
main() {
float tc, tf = 90., conv;
float offset = 32.;
conv = 5./9.;
tc = (tf – offset) * conv;
}
Cosa accade se eseguo il programma?
Nulla, perché non ci sono istruzioni di output!
Input/Output
90.000000 F = ...
Input/Output
90.000000 F = 32.222222 C
>
Emissione dei dati attraverso
printf()
Questa funzione permette di formattare l’output
int printf(<stringa-formato>[,<espressione>]…)
La stringa di formato può essere costituita
da tre componenti:
(obbligatoria) una costante stringa ;
(opzionali) metavariabili e sequenze di
escape
Opzioni di visualizzazione di
caratteri
Principali caratteri di conversione
(output)
descrittore tipo
%f,%e float,double
%d,%i int
%c char (singolo)
%s char (stringa)
Principali codici di escape
codice descrizione
\n newline
\t Tabulazione oriz.
\a alert
scanf(“%f”, &tf);
Input/Output
scanf(“%f”, &tf);
90
Input/Output
scanf(“%f”, &tf);
90 = (1+0.40625)26
010000101011010000000000...
(1/4 + 1/8 + 1/32)
Input/Output
scanf(“%f”, &tf);
90 = (1+0.40625)26
010000101011010000000000...
90.
Principali caratteri di conversione
(input)
descrittore tipo
%f float
%lf double
%d,%i int
%c char (singolo)
%s char (stringa)
scanf()
ATTENZIONE:
Se si inseriscono spazi o invio nell'immissione
di più caratteri (tra un carattere e un altro) è
necessario inserire anche questi nella stringa
di formato tra i segnaposto %c
scanf(“ %c”,&ch);
Lo spazio prima del segnaposto cattura lo
spazio, tabulazione orizzontale, newline
Importanza della
rappresentazione
tf = 5 / 9 * (tc – offset);
Preelaborazione
Direttive al preprocessore
Preprocessore: programma che “esegue” istruzioni
dette direttive di inclusione e definizione
#include
Consente di includere il contenuto di un altro
file o librerie
#define
Definisce un simbolo (Attenzione!!!)
#ifdef, #ifndef, #else
Compilazione condizionale
#include
#include <stdio.h>
per input/output
#include <stdlib.h>
allocazione dinamica della memoria,
generazione numeri casuali, exit, time
#include <math.h>
libreria matematica
sin(x), cos(x), sqrt(x), exp(x),
pow(x,y),
log(x), fabs(x), iabs(x)
#define NOME MACRO
Un Integrated Development Environment (IDE), in italiano
ambiente integrato di sviluppo, è un software che aiuta
i programmatori nello sviluppo del codice
Esempi:
Dev-C++ (Windows)
Eclipse (Linux, ma anche Windows e Mac)
XCode (Mac)
...
Compilatore e IDE sono la stessa cosa? NO!
Negli esempi indicati, il compilatore è sempre gcc!
Tali IDE integrano un editor di testi che agevola il programmatore, per poi
lanciare “in modo trasparente” il compilatore gcc, esattamente come
abbiamo descritto qualche slide fa!
Sono solo programmi di supporto!
In alcuni casi il compilatore non è “scindibile” dall’IDE (es: Visual Studio)
Esempio di IDE
Click sul tasto “Compila”
Esecuzione di gcc!