Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


informatica teoria (appunti e dispense), Appunti di Informatica gestionale

Appunti presi a lezione integrati con la dispensa e le slide, relativi alla parte teorica del corso

Tipologia: Appunti

2020/2021

In vendita dal 29/08/2023

emma-vergani
emma-vergani 🇮🇹

4

(1)

5 documenti

1 / 20

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
1 di 20
CODIFICHE
- Notazione posizionale: permette di rappresentare un qualsiasi numero naturale (intero non
negativo) nel modo seguente:
o la sequenza di cifre: cn-1 cn-2 … c1 c0
o rappresenta in base B=2 il valore: cn-1XBn-1 + cn-2xBn-2 + … + c1xB1 + c0xB0 dove: c di i
appartiene a 0, 1, 2, …, B-1 per ogni 0 <= i <= n-1
es: 231bin = 2x2^2+3x2^1+1x2^0
-
le varie basi: (es. numero 29)
!
base decimale: B=10 A= {0,1,2,3,4,5,6,7,8,9} 29dec =29
!
base ottale: B=8 A={0,1,2,3,4,5,6,7} 29dec = 358 = 3x81 + 5x80
!
base esadecimale: B=16 A={0,1,2,3,4,,9,A,B,C,D,E,F} 29dec = 1D16 = 1x161 + 13x160
!
base binaria: B=2, A={0,1} 29dec = 111012 = 1x24 +1x23 +1x22 +1x20
codiche notevoli: esadecimale16(16), ottale8 (8), binaria2 (2)
LA CODICA BINARIA
usata dal calcolatore per la codifica di tutte le informazioni, codifica in BIT ("BInary digiT), è
l#unità elementare dell#informazione. {0,1} possono essere associati a due stati opposti
(ON/OFF).
nella codifica binaria classica con 1Byte = sequenza di 8 BIT si possono rappresentare tutti i
numeri che vanno da: 0 = 00000000bin a 255dec=11111111bin
A.
conversioni:
da decbin: metodo dei resti:
nb! se il numero è dispari termina con 1, se pari termina con 0
nb! aggiungere uno zero in fondo = moltiplicare il numero per la base, se aggiungo un 1 in
fondo = moltiplicare il numero per la base e aggiungere 1 (es 9dec=1001bin ; 10010bin=
9x2dec=18dec ; 10011bin= 9x2dec=19dec)
da bindec: sommatoria: ∑=cn-1 x2n-1 +cn-2 x2n-2 +...+c0 x20 (es.10011bin =1x24
+0x23 +0x22 +1x21 +1x20=16+0+0+2+1=19)
—>conversioni rapide, notazione abbreviata con errore10% (approssimato per difetto
nel caso bin → dec, approssimato per eccesso o difetto nel caso decbin):
-K=210~103 (KILO)
-Mi=220~106 (MEGA)
-Gi=230~109 (GIGA)
-T=240~1012 (TERA)
si può utilizzare per scomporre potenze di 2 elevate a partire dalle prime 9 :
20 =1; 21 =2; 22 =4; 23 =8; 24 =16; 25 =32; 26 =64; 27=128; 28 =256; 29 =512; 210
=1024; 211 =2048; 212 = 4096;
(es.217 =27 x210 ~128x103 ~128KILO =128000
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14

Anteprima parziale del testo

Scarica informatica teoria (appunti e dispense) e più Appunti in PDF di Informatica gestionale solo su Docsity!

CODIFICHE

  • Notazione posizionale: permette di rappresentare un qualsiasi numero naturale (intero non

negativo) nel modo seguente:

o la sequenza di cifre: cn- 1 cn- 2 … c1 c

o rappresenta in base B=2 il valore: cn-1XBn- 1 + cn- 2 xBn- 2 + … + c1xB1 + c0xB0 dove: c di i

appartiene a 0, 1, 2, …, B- 1 per ogni 0 <= i <= n- 1

es: 231bin = 2x2^2+3x2^1+1x2^

le varie basi: (es. numero 29)

! base decimale: B=10 A= {0,1,2,3,4,5,6,7,8,9} 29 dec

! base ottale: B=8 A={0,1,2,3,4,5,6,7} 29 dec

= 3x

  • 5x

! base esadecimale: B=16 A={0,1,2,3,4,…,9,A,B,C,D,E,F} 29 dec

= 1D

= 1x

  • 13x

! base binaria: B=2, A={0,1} 29 dec

= 1x

+1x

+1x

+1x

codiche notevoli: esadecimale 16

(16), ottale 8

(8), binaria 2

LA CODICA BINARIA

usata dal calcolatore per la codifica di tutte le informazioni, codifica in BIT ("BInary digiT”), è

l#unità elementare dell#informazione. {0,1} possono essere associati a due stati opposti

(ON/OFF).

nella codifica binaria classica con 1Byte = sequenza di 8 BIT si possono rappresentare tutti i

numeri che vanno da: 0 = 00000000 bin

a 255 dec

bin

A. conversioni:

da dec → bin : metodo dei resti :

nb! se il numero è dispari termina con 1, se pari termina con 0

nb! aggiungere uno zero in fondo = moltiplicare il numero per la base, se aggiungo un 1 in

fondo = moltiplicare il numero per la base e aggiungere 1 (es 9 dec

bin

bin

9x dec

dec

bin

= 9x dec

dec

da bin→dec: sommatoria : ∑=c n- 1

x

n- 1

+c n- 2

x

n- 2

+...+c 0

x

(es. bin

=1x

+0x

+0x

+1x

+1x

—>conversioni rapide, notazione abbreviata con errore ≤10% (approssimato per difetto

nel caso bin → dec, approssimato per eccesso o difetto nel caso dec → bin):

- K=

3 (KILO)

Mi=

6 (MEGA)

Gi=

9 (GIGA)

T=

12 (TERA)

si può utilizzare per scomporre potenze di 2 elevate a partire dalle prime 9 :

(es.

x

~128x

~128KILO =

B. Operazioni sui numeri binari

  • in memoria: i numeri binari sono memorizzati in registri che contengono sequenze di bit

predefinite, nessun bit può essere vuoto (se il numero è più corto di 8 bit allora è preceduto

da tutti zeri);

  • addizione e sottrazione:

algoritmo di addizione a propagazione dei riporti :

0+0 = 0, 1+0 = 1, 1+1=0 con riporto di 1, eseguo una semplice somma addendo per

addendo.

Se il riporto è sull#ultima colonna allora significa che tale numero non è rappresentato su 8

bit (max 255) → ottengo errore! un risultato errato, riporto perso = ho overow :

superamento del limite di rappresentazione, il valore del risultato non può essere

rappresentato con le cifre a disposizione

log2 valore Numero di bit per rappresentare il valore

es: log2 (8)= 3 – servono 3 bit per rappresentare il valore 8

C. numeri interi in modulo e segno , m&s : il primo bit a sx rappresenta il segno ed è

applicato al numero, togliendo il primo bit si ottiene il valore assoluto

0 segno positivo, 1 segno negativo es.

0 00001000m&s = +2^3=+8dec 1 00001000m&s= - 2^3=-8dec

D. numeri interi in complemento a due C2 :

primo bit a sx è detto bit di segno ed è interpretato con valore negativo(-1)→(-b n- 1

)x

n-

+b n- 2

x

n- 2

+...+b 0

x

, il bit di segno non è separabile dagli altri bit ma è integrato ed

infatti ha anche valore di modulo.

0 = segno positivo, 1= segno negativo

permette di rappresentare sia interi positivi sia interi negativi, i bit rimangono comunque 8,

però questa volta si potranno rappresentare solo numeri da: - 128 a +127 (- 2

n- 1

< n <

n- 1

)

—>l# inverso addittivo (o opposto) di un numero n codificato in C2 si ottiene

  1. invertendo (negando) ogni bit del numero

  2. sommando uno alla posizione a dx tenendo conto di eventuali riporti.

(es 11011 C

dec

C

dec

—> conversione dec → C2 :

se dec > 0 : converto il decimale in binario naturale e aggiungo in bit 0 davanti a sx (es

dec

bin

C

se dec < 0 : converto in binario naturale come se fosse un numero positivo, aggiungo il bit

0 davanti ed eseguo l’inverso additivo

—> Estensione del segno: replicando in modo progressivo il bit di segno a sinistra, il

ott

→ due tre sei cinque tre tre → 010 011 110 101 011 011 → 010011110101011011

da bin →

hex: 010011110101011011 → 0001 0011 1101 0101 1011 → uno tre tredici cinque undici →

13D5B

hex

hex → bin:

A7B40C

hex

→ dieci sette undici quattro zero dodici → 1010 0111 1011 0100 0000 1100

NUMERI FRAZIONARI IN VIRGOLA FISSA :

  • sono rappresentabili in bit
  • le potenze prima della virgola hanno esponente positivo, le potenze dopo la virgola hanno

esponente negativo, la porzione intera e frazionaria sono costanti.

es. 0, bin

=0x

, 1x

  • 0x
  • 1x
  • 1x

dec

dec

virgola fissa

A. conversione dec → bin: converto la parte intera con il metodo dei resti + parte frazionaria

con il metodo dei prodotti

metodo dei prodotti :

Posso ottenere anche un

numero periodico se nelle

moltiplicazioni i resti si

ripetono, i periodo sono le

moltiplicazioni che intercorrono tra i due resti

es: 0,675dec 0,101(0110)bin

NUMERI FRAZIONARI IN VIRGOLA MOBILE:

si possono rappresentare con pochi bit numeri molto grandi oppure valori frazionari molto

piccoli (cioè con molti decimali). N°bit=bit M+ bit E

La rappresentazione si basa sulla relazione

R

virgola mobile

= M x B

E

M = mantissa numero frazionario rappresentante le cifre significative dopo la virgola, m≥ 1 bit

B = base 2, E = esponente, n≥ 1 bit

sia mantissa (solitamente in m&s) che esponente possono essere negativi

  • attenzione: meno cifre si hanno nella mantissa più il numero è approssimato (più grande è il

numero più grande è l#errore dell#approssimazione), sono rischiose lo operazioni tra numeri

aventi ordini di grandezza molto diversi

ARITMETICA STANDARD IEEE 754 :

quasi tutti i calcolatori oggi adottano lo standard aritmetico IEEE 754, che definisce:

1 - i formati di rappresentazione: binario naturale, C2 e virgola mobile;

2 - gli algoritmi somma, sottrazione, prodotto, ecc.. per tutti i formati previsti;

3 - i metodi di arrotondamento per i numeri frazionari;

4 - la gestione degli errori (overflow, divisione per 0, rad quadrata di numeri negativi, ...).

la definizione dello standard IEEE 754 permette di trasportare programmi tra calcolatori diversi

senza mutare risultati o precisione di calcolo.

CODIFICA DEI CARATTERI

  • nei calcolatori i caratteri sono codificati mediante sequenze di n≥ 1 bit rappresentanti

ciascuno un carattere;

  • il codice ASCII (American Standard Computer Interchange Interface): codifica a

7 bit e comprende 128 caratteri pensati per la lingua inglese.

(ASCII Esteso a 8 bit, 256 caratteri, comprende anche caratteri speciali e lettere

accentate necessarie alle lingue europee) il codice comprende: spazi, tabulazione,

sound bell (e altri caratteri non stampabili), punteggiatura, caratteri alfa-numerici

  • altre codifiche: ISO-X rappresenta sistemi di scrittura internazionali (es. ISO-

LATIN) → poi è stato esteso a UNICODE per creare una codifica universale

  • è possibile codificare anche:

testi → sequenze di carattere (seq. di bit)

immagini → bitmap con sequenze di pixel (puntini di n colori), jpeg, gif, etc musica →

mid, wav, mp3, etc

video → seq. di immagini + suoni

  • dentro al calcolatore: vengono memorizzati in parole di memoria ( che possono

contenere sequenze di n ≥ 1 bit, n = 8, 16, 32 o 64 bit) = celle che compongono la

memoria a ciascuna delle quali corrisponde un indirizzo.

Ciascuna parola di memoria può memorizzare un elemento d#informazione diverso: un

carattere (o più), un numero bin naturale o in C2, un numero frazionario con virgola

mobile.

Alcuni bit della parola possono non essere utilizzati.

  • analogamente per quanto riguarda i registri della CPU

(es. parole di memoria:)

ALGEBRA DI BOOLE E ELEMENTI DI LOGICA

serve per formalizzare attraverso operazioni logiche le operazioni del calcolatore.

L#algebra booleana utilizza due operandi logici:

1=VERO, 0=FALSO

—> operatori logici binari:

OR (somma logica)

AND (prodotto logico)

—> operatore logico unario:

NOT (negazione o inversione ) e rispettive tabelle di verità

dischi a memorizzazione ottica (DVD e Blu-ray) in cui però la velocità di accesso non è

uniforme in tutte le parti del disco. I più efficaci sono tuttavia le memorie a stato solido,

(SSD (Solid State Drive)) che garantiscono una velocità di accesso ai dati

indipendentemente dalla loro posizione in memoria.

  • Le informazioni all#interno della MdM sono raggruppate in file gestiti dal sistema

operativo, che li divide e organizza per tipo attraverso indici (estensioni .pfd .png etc)

che ne garantisce un accesso veloce.

! MEMORIA CENTRALE (RAM + ROM)

- area di memoria contenente dati e programmi (in linguaggio macchina) su cui la CPU

può operare, e ha tempi di accesso molto brevi rispetto a mm.

  • Tutte le informazioni su cui agisce la CPU devono passare per la Memoria Centrale e

sono successivamente caricate in uno dei registri della CPU (= piccole unità di

memoria volatile).

  • rispetto a memoria di massa è memoria a breve-medio periodo ed è volatile perchè si

spegne allo spegnimento della macchina

  • dimensione della mc sono ridotte—> ordine dei Gbyte.
  • Struttura:

insieme ordinato di parole di memoria (=celle) a parola = n elementi binari (8, 16, 32,

64 bit)

la posizione di ciascuna cella è definita da un indirizzo —> la capacità di indirizzamento

della ram è definita dalle dimensione di bus indirizzi e registro indirizzi

  • due tipi di memorie:

a. LA RAM (RANDOM ACCESS MEMORY)

  • realizzata mediante circuiti a transistori
  • consente l#accesso diretto e rapido (il tempo di accesso non dipende dalla cella) a tutte

le celle, indipendentemente dalla posizione

  • è modificabile ed ha bisogno di un alimentatore per conservare le informazioni.

b. LA ROM (READ ONLY MEMORY)

- costituita dalla stessa tecnologia della Memoria di massa

  • contiene dati e programmi protetti scritti una sola volta dal costruttore al momento

della produzione e non modificabili

nb! all#accensione del pc la RAM contiene una sequenza casuale di 01 mentre la ROM

contiene il bootstrap, programma contenente le prime istruzioni che la CPU deve

svolgere.

—> Indirizzamento della RAM

gli indirizzi i di ciascuna parola corrispondono a un valore numerico intero positivo

espresso in binario su un certo numero di bit

=> k bit possono indirizzare 2

k

celle (es. con 10 bit indirizzo 2

= 1024 celle, 20 bit un

mega di parole, 30 bit un giga, 40 bit un tera).

All#interno della CPU vi è un registro indirizzi che contiene tutti gli indirizzi i delle celle

da cercare, quindi l#indirizzo i della cella viene scritto sul registro indirizzi e da qui viene

mandato tramite il bus indirizzi alla ram.

! CPU

contiene gli elementi circuitali che regolano il funzionamento della macchina

formata da:

a. UNITÀ DI CONTROLLO (UC) = responsabile della decodifica ed esecuzione delle

istruzioni, dirige l#azione delle altre parti.

—>Il formato delle istruzioni è il linguaggio macchina

è costituito da sequenze di 01

contiene:

  1. il campo codice operativo che specifica l#istruzione da eseguire

  2. il campo operandi che indica, per valore o indirizzo, i dati da utilizzare (possono

essere 0, 1, 2).

formato istruzione =

b. UNITÀ ARITMETICO-LOGICA (ALU) = esegue le operazioni aritmetico logiche fra

registri A e B in ingresso, non ha facoltà di scelta

c. REGISTRI = piccole memorie velocemente accessibili utilizzate per memorizzare

dati temporanei, dati di controllo e risultati parziali durante le operazioni di calcolo

L#insieme dei contenuti dei registri in un dato istante è detto contesto.

d. OROLOGIO DI SISTEMA (CLOCK) = elemento di sincronizzazione che

temporarizza le varie operazioni del calcolatore.

—> LOAD (lettura da MC)

  1. la CPU carica l’indirizzo della parola di memoria nel registro indirizzi e lo trasmette

alla memoria via bus indirizzi

  1. la CPU invia il comando di read memory sul bus di controllo

  2. la memoria trasmette sul bus dati il contenuto della parola verso il registro dati

  3. la memoria segnala al processore sul bus di controllo che l’operazione è stata

completata con successo: il dato si trova nel registro dati

—>STORE (scrittura da MC)

  1. la CPU carica l’indirizzo della parola di memoria dove si vuole scrivere nel registro

indirizzi e lo trasmette alla memoria via bus indirizzi

  1. la CPU carica nel registro dati la parola da scrivere in memoria

  2. la CPU invia il comando di write memory sul bus di controllo

  3. la CPU trasmette sul bus dati il contenuto del registro dati verso l’indirizzo di

memoria segnalato

  1. la memoria segnala al processore sul bus di controllo che l’operazione è stata

eseguita con successo: il dato si trova nella parola di memoria destinazione

• UNITÀ PERIFERICHE (I/O)

consentono la comunicazione con l#ambiente esterno (anche se non sempre con utente

umano).—> le periferiche dati sono collegate al bus tramite interfacce : dispositivi

(elettronici o elettromeccanici) che traducono elementi periferici per il collegamento con

l#elaboratore tramite il bus.

Le interfacce contengono:

  • Registro Comandi Periferica PCR per inviare comandi alla periferica ed è collegato al

bus di controllo

  • Registro Dati della Periferica PDR per scambiare dati ed è collegato al bus dati
  • Registro Stato Periferica PSR per controllare il corretto funzionamento della periferica

(es. pronta, occupata, errore).

per macchine più moderne:

• IL SISTEMA OPERATIVO SO

  • è un programma complesso che permette all#utente di interagire con il calcolatore
  • funzioni:
  1. supporto per la programmazione

  2. meccanismi di ingresso e uscita

  3. gestione archivi (file).

—> da codice in C a in assembler (?)

nb! il compilatore deve decidere prima quanto spazio allocare per le variabili.

nb! la corrispondenza posizionale tra i %d e le variabili di traduce in un preciso ordine di

istruzioni READ in assembler

MEMORIA

ogni espressione ha : un TIPO ed un VALORE

ARRAY = variabile strutturata in cui si memorizzano più valori tutti dello stesso tipo

  • omogeneo
  • elementi con un indice=posizione di elementi in array
  • memorizzati in celle di memoria consecutive
  • numero di elementi è predeterminato e costante (si sa prima di esecuzione)
  • tipi derivarti, perchè per essere definiti fanno riferimento a dei tipi base

inizializzazione —> v[5]={1,2,3,4,5} 5=num elementi, 1 ha indice zero..

MATRICI = array bidimensionali

dati organizzati per righe ‘i' e colonne ‘j’, elementi anche qui specificati prima

mat[4][5] 4=riga, 5=colonna

prodotto tra matrici <=> numero di colonne di prima mat è uguale a numero di righe della

seconda mat

risultato è matrice con stesso numero di righe e colonne

es:

1 2 3 x 1 1 = 1x1+2x1+3x0 1x1+2x5+3x2 = 3 17

0 1 3 2 5 0x1+1x2+3x0 0x1+1x5+3x2 2 11

matrice quadrata<=> i=j

trasposta - > inverto elementi di colonna con quelli di riga intorno a diagonale principale

si ha trasposta solo di mat quadrata

se matrice=matrice trasposta - > mat è simmetrica

STRINGHE = array di caratteri

es. char a[ ]=“parola” —> array di 7 eletti= 6caratteri+ termine tappo—>’\ 0 ’ che termina la

stringa

  • char a[ ]=“r” significa che l’array è composto solo da due elementi(r, \0)
  • char a[ ]=‘r’ significa assegnare al primo elemento di array ‘r’

dove “r” è una striga costante mentre ‘r’ è una costante di tipo char

—> non sono un tipo base di dato => aggiungere propria libreria #string.h

  • quando utilizziamo scanf con stringhe legge fino a prima di incontrare uno spazio, il resto non

viene considerato - > per leggere tutta stringa usare getchar()

—> il nome dell’array rappresenta l’indirizzo del suo primo elemento perciò con scanf non

necessario una & es. scanf(“%s”, stringa)

—> se scanf acquisisce stringa troppo lunga, questa è memorizzata oltre la fine dell’array =

errore grave

array => collezioni di variabili omogenee

struct => collezioni di variabili eterogenee

STRUCT = variabile strutturata in cui si memorizzano più valori (dati , che in struct sono

chiamati campi) di tipo differente

  • definiti fuori da funzione
  • contenitore di elementi eterogenei
  • definizione esempio:

struct data { //data è un nuovo tipo di dato che si può usare nel main

int giorno;

char mese[ ];

int anno;

—> per accedere ai campi della struttura usare ‘.’

esempio (nel main)

struct data oggi;

oggi.giorno=25;

oggi.anno=2020;

oggi.mese=“dicembre”

quindi

printf (“%d”, oggi.anno) stamperà 2020

—> posso copiare elementi di una struct in un’altra struct (solo se sono dello stesso tipo)

attraverso = —> esempio:

struct data oggi;

struct data compleanno;

compleanno=oggi; //assegna valori di oggi a compleanno

DEFINIZIONE DI NUOVI TIPI = TYPEDEF

  • esempio:

typedef int {intero}; nel main posso definire con nuovo tipo—> intero numero;

  • es di una definizione di una variabile strutturata eterogenea (struct) :

typedef struct{

char nome[20];

char cognome[20];

int annoNascita;

int codiceFiscale[30];

} persona;

  • esempio di definizione di una variabile strutturata omogenea (array) :

typedef char {

ventiCaratteri [20]

ventiCaratteri nome, cognome; = nome e cognome sono di tipo ventiCaratteri, ovvero due

array di 20 char

PUNTATORI

  • sono variabili il cui valore corrisponde all’indirizzo (numero di cella) di un’altra variabile =>

sono delle variabili abilitate a contenere un indirizzo

  • & : operatore di referenziazione => restituisce l’indirizzo di memoria di una variabile

es. &a = restituisce l’indirizzo di memoria della variabile a

    • : operatore di deferenziazione => viene applicato a variabile tipo puntatore e restituisce il

contenuto dell’oggetto puntato, perciò estrae il valore contenuto nella cella puntata (permette

di andare a modificare il valore del puntatore)

  • tipoBase *variabilePuntatore => variabilePuntatore è creta per mantenere l’indirizzo di

variabili di tipoBase —> puntatore è un tipo derivato perché occorre specificare a che

indirizzo punta

es. int *p => p punta ad un intero

se ho void *p => non viene specificato il tipo di indirizzo di memoria a cui punta, può puntare

a qualsiasi variabile

  • esempio:

int x=

int *p

p= &x //è analogo a scrivere int *p = &x

//il valore di p corrisponde all’indirizzo di x => p contiene l’indirizzo di x

printf (“il valore di x è %d”, *p) //il valore stampato è 3 quindi dopo l’assegnazione p= &x *p

e x sono perfettamente equivalenti

—> l#indirizzo della cella i-esima è: v + i //la dereferenziazione di tale valore permette di

accedere al contenuto della cella i-esima

—> differenza tra array e puntatori:

Essendo array di tipo int *const il suo indirizzo non può essere modificato durante l#esecuzione

del programma. Quello di punt può invece essere modificato liberamente.

—> Con la seguente dichiarazione:

int a[5], i, *p;

a[i] //equivale a *(a + i);

p = a; //equivale a p = &a[0];

p = a + 1; //equivale a p = &a[1];

a = p; //è un ERRORE !!

a = a + 1; //è un ERRORE !!

A è il nome di un array, quindi un puntatore costante. L#indirizzo dell#array non può essere

modificato.

—> Se p e q puntano a due diversi elementi di uno stesso array:

int v[5] = {14, 16, 8, 9, 12};

int *p = &v[3], *q = &v[1];

la differenza: p – q dà la distanza tra gli elementi puntati espressa in numero di celle dell#array

FUNZIONI

  • sono dei sottoprogrammi , che a dei valori in ingresso fanno corrispondere (restituiscono) dei

valori in uscita

tipo_funzione nome_funzione (tipo_variabile variabile1, tipo_variabile variabile2) {

dove tipo_funzione corrisponde al tipo che viene restituito, mentre tipo_variabile corrisponde al

tipo che viene inserito

  • come funziona:

! Dichiaro la funzione prima del main (dichiarazione)

! Specifico i passaggi della funzione in { } (definizione ). La funzione restituisce un valore

(return valore;) dello stesso tipo della funzione. Le funzioni che non restituiscono valori sono

di tipo void (dette anche procedure ) —> l#istruzione del return è assente, la funzione termina

quando il flusso di esecuzione arriva alla } finale.

! Invocazione: quando uso la funzione all#interno del main.

  • due tipi di parametri:

formali = parametri presenti nella definizione (es. variabile1, variabile2)

attuali = parametri dati al momento dell’invocazione nel main —> i tipi devono corrispondere

  • tre tipi di funzioni:
  1. procedure senza valore di ritorno (main)
  2. funzioni con valore di ritorno
  3. funzioni/procedure con effetti collaterali —> per modificare una variabile dichiarata in una

funzione all’interno dell’ambiente chiamante occorre utilizzare i puntatori => ovvero uso i

puntatori quando non ho un valore di ritorno e scopo è modificare un parametro nel main e

non restituire un valore

  • esempio di funzioni (con anche puntatori):

Void modifica_dato (int *dato) {

*dato=4; //il valore della cella puntata da dato è 4

int nuovo_dato (int dato) {

Dato=1;

Return dato; }

Int main () {

Int dato =0;

printf("dato: %d\n”, dato);

nuovo_dato(dato); //il valore della variabile nel main rimane zero, perché non ho

assegnato il valore di ritorno della funzione a nessuna variabile.

printf("dato: %d\n”, dato); //stampa zero

dato = nuovo_dato(dato); //ho assegnato il valore di ritorno della funzione alla variabile.

Quindi la mia variabile ha cambiato valore.

printf("dato: %d\n”, dato); //stampa 1

modifica_dato (&dato); //modifico il dato anche senza avere un valore di ritorno e senza

assegnare a nessuna variabile il mio valore di ritorno (è una funzione void). (Quindi posso

andare a modificare il valore di una variabile senza assegnare a questa un valore di ritorno)

printf("dato: %d\n”, dato); //qui il dato si modifica —> stampa 4. Il dato è stato modificato nel

main

//quando io uso i puntatori modifico la variabile a livello globale (nel main).

—> per modificare i parametri attuali con i puntatori

  1. Nella definizione della funzione il parametro deve essere di tipo puntatore (*p)
  2. Nella chiamata si deve passare l#indirizzo (usando &) del parametro attuale da modificare

(&varLocale)

  1. Nel corpo della funzione si usa l#operatore “ * " di dereferenziazione per riferirsi al valore del

parametro (*p)

FILE

caratteristiche:

- Il file è l#unità logica di memorizzazione dei dati su memoria di massa, che consente una

memorizzazione persistente dei dati, non limitata dalle dimensioni della memoria centrale.

Ogni programma vede il file come una sequenza di componenti (record logici), terminata da

una "marca” di fine file (End Of File —> EOF).

= sono degli archivi che:

permettono il salvataggio persistente dei dati su un supporto fisico

il caricamento dei dati su un supporto fisico in momenti successivi al salvataggio

—>libreria necessaria per interagire con file: stdio.h

tipo:

binario => sequenza di byte

testo => sequenza di caratteri

  1. dichiarazione: FILE *fp —> fp è chiamata file pointer
  2. apertura: fp = fopen (“nomeFile.txt”, “modalità di apertura”) —> l’operazione di apertura

restituisce il file pointer (infatti il valore di ritorno della funzione viene assegnato alla

variabile fp), che viene associato a nomeFile.txt

  1. controllare che file esista: if (fp == NULL) o if(!fp) { printf(“errore in apertura del file”);

return-1}

  1. interazione con il file (scrittura o lettura)
  2. chiusura dal file: fclose (fp)

—>modalità di utilizzo:

“r” = read => permette di leggere elementi del file, la testina (=indicatore della posizione

corrente nel file) è posizionata all’inizio del file

“w” = write => permette di scrivere su file, gli elementi precedentemente contenuti vengono

eliminati e la testina è posizionata all’inizio del file (per scrivere su file senza cancellare

elementi precedenti usare “a” = append)

—> descrittore:

MEMORIA DINAMICA

  • soluzione alternativa per dimensionamento array
  • tramite memoria dinamica posso allocare dei dati durante la fase di esecuzione del

programma e non prima

#include <stdlib.h> —> permette di utilizzare funzioni per l#allocazione e il rilascio dinamico

di memoria

  • la memoria viene allocata dinamicamente tramite la funzione malloc:

void* malloc (n°di byte da allocare di un certo tipo);

—> il tipo non viene specificato, ma è compito del programmatore determinarne il tipo

—> restituisce un puntatore di tipo void che punta alla memoria allocata (una variabile senza

nome, che può essere utilizzata solo tramite il suo puntatore)

—> la funzione malloc crea in memoria una variabile di un certo tipo e restituisce l’indirizzo del

byte riservato in memoria alla variabile

es. pi = (int *) malloc(sizeof(int)) —> l’istruzione alloca dinamicamente in memoria una

quantità tale da poter accogliere un intero ; questo intero allocato dinamicamente e di cui non

si conosce il nome, può essere raggiunto solo tramite il puntatore pi.

In particolare (int *) permette di assegnare l’indirizzo del primo byte dell’intero a pi, dopo

aver convertito il tipo void* (ritornato da malloc) nel tipo int* —> chiamo cast (=conversione da

un tipo ad un altro)

—> se non vi è più memoria disponibile malloc restituisce NULL

  • se si vuole recuperare spazio gli oggetti dinamici devono essere deallocati esplicitamente

dalla memoria, tramite free:

void free (void *ptr);

—> libera la memoria precedentemente allocata per il puntatore ptr

es:

char *ptr

ptr = (char*) malloc(sizeof(char))

*ptr = ‘a’ // scrivo nella memoria riservata da malloc ‘a’

printf (“%c”, *ptr)

free (ptr) //non viene eliminato ptr ma il valore presente nella memoria a cui puntava ptr,

quindi ora in memoria non sarà più presente ‘a’

  • memoria divisa in tre parti:
  1. segmento data = dati —> contiene le variabili statiche e globali
  2. segmento stack = pila —> conțiene le variabili automatiche (=dichiarate nelle funzioni)
  3. segmento heap = mucchio —> contiene le variabili dinamiche
  • rischi della gestione dinamica della memoria:

! produzione di garbage => si verifica quando memoria allocata dinamicamente è

inaccessibile (es non uso la free prima di far puntare puntatore che puntava a memoria

dinamica ad un’altra variabile, quindi quella variabile occupata un’area di memoria che

risulta essere inutilizzabile)

! puntatori fluttuanti => che puntano ad aree di memoria che sono già state deallocate

! dangling refereces (riferimenti fluttuanti): creazione di riferimenti fasulli a zone di memoria

inesistenti. – più rischiosa

  • void* calloc (size_t numEle, size_t eleDim); //alloca dinamicamente in memoria il numero di

elementi numEle elementi di dimensione eleDim