Appunti di programmazione

Appunti per il corso universitario di programmazione, riferito al linguaggio ANSI C
Redatti all'università di Venezia

ARGOMENTI

STRUTTURA COMPUTER

DEFINIZIONI

TASTIERA E TIPI

AMBIENTE E MEMORIA

COMANDI

FUNZIONI E PROCEDURE

TIPI DERIVATI

PUNTATORI

STRINGHE

ARRAY DI PUNTATORI

STRUTTURE

TYPEDEF E ENUM

PUNTATORI A PROCEDURE

ALLOCAZIONE DINAMICA

LISTE

ALGORITMI

ERRORI

FUNZIONE DI GESTIONE DELL’'INPUT E DELL’'OUTPUT

Per poter utilizzare le funzioni scanf e printf è necessario inserire all’inizio del testo la linea

#include <stdio.h>

che avverte il compilatore di includere i riferimenti alla libreria standard di input/output.

stdio sta per standard input/output

es.

printf(“Area: %d\n”, area);

Il simbolo di percentuale % specifica che il carattere che lo segue definisce il formato di stampa del valore della variabile area.

Caratteri di formato:

d (decimal) per visualizzare un intero

f o lf (floating point) per visualizzare un reale

c (char) per visualizzare un carattere

s (string) per visualizzare una stringa di caratteri

es.

printf(“Area: %d\n”, area);

la sequenza \n provoca un salto a linea nuova dopo la visualizzazione del valore della variabile area.

Sequenze di escape:

\n va a linea nuova

\t salta di una tabulazione

\b ritorna un carattere indietro (backspace)

\a emette un suono (bip della macchina)

\\ stampa il carattere

\\” stampa il carattere ”

es.

scanf(“%d”, &altezza);

la funzione scanf legge un intero dallo standard input e memorizza il risultato nella locazione di memoria corrispondente all’indirizzo &altezza che è l’indirizzo della variabile altezza

scanf restituisce il numero di valori che sono stati letti con successo, quindi:

int a = scanf(...);

a conterrà il numero di caratteri letti

attenzione: se aggiungo uno spazio prima del % leggendo i caratteri scanf ignorerà tutti i primi spazi o tab:

int a = scanf(“ %c”,&bho);

GETCHAR E PUTCHAR

stdio.h

getchar legge un carattere dallo standard input, putchar scrive un carattere nello standard input

int getchar(void);

int putchar(int); // ricordando che anche un carattere è un intero

TIPI PREDEFINITI

INT

RANGE

almeno 16 bit sono allocati per ogni variabile ? valori [-32767...+32767]

OPERATORI

  • unari: – (int x = 7; int y; y = -x;), + (anche se non ha alcun effetto)

  • binari: + - / % *

QUALIFICATORI

  • short (utilizza 8 bit anziché 16, non per tutti i compilatori ? portabilità non garantita)

  • long (32 bit)

PRECEDENZE TRA GLI OPERATORI

  • matematiche MA % = modulo è un operatore moltiplicativo ? 15 + 3 %7 = 15 + (3 % 7)

  • in caso di operatori con lo stesso livello di precedenza applico l'associatività da sx a dx es. 5+3-2+4 = (((5+3)-2)+)4)


RIASSUMENDO...

  1. un'espressione ha sempre un tipo

  2. una variabile ha sempre associato un tipo

  3. un valore appartiene sempre a un tipo

int pippo = pluto = 5;

int pippo = (pluto = (5 + 3));

DOUBLE

es. 16.0 double x = 16.0; (completamente diverso da 16 di tipo int)

notazione standard = 6.0E23

OPERATORI

  • stessi operatori degli interi ma senza il modulo; la divisione si comporta in modo diverso (int: 4/3 = 1; double: 4.0/3.0 = 1.333333333)

CASTING

int x = 7300;

double y = 17494999.0;

double z = 3.0;

è possibile scrivere:

y = x;

perchè c'è una promozione automatica (casting implicito) al tipo double, ma è meglio renderla esplicita (casting esplicito):

(<tipo>)<espressione>

() viene detto operatore di cast

es.

y = (double) x;

lo si può fare per qualsiasi valore di x poiché il range del tipo double è maggiore di quello del tipo int

posso scrivere anche:

x = z; //(troncamento automatico)

o meglio:

x = (int) z;

devo controllare se il valore della seconda variabile convertita è nel range del tipo della prima variabile


double x;

x = 3.0 + (3/1.5); mi aspetto il casting implicito di 3

int lunghezza = 104;

int Area = 2136;

double larghezza;

larghezza = Area / lunghezza;


“Area / lunghezza” viene valutata per prima ? è una divisione fra interi ? troncamento

z = 4.0 * (3/4) ? z = 0.0

z = 4.0 * (3.0/4) ? z = 2,999...

REGOLE DEL CASTING IMPLICITO

  • esegue tutte le operazioni promuovendo gli operandi al tipo con il range maggiore (effettuando eventualmente dei troncamenti)

  • effettua il casting del risultato al tipo della variabile in cui questo deve essere contenuto (effettuando eventualmente un troncamento)

es.

6 + 5/4 –3 =

6 + 5.0/4.0 – 3 =

6 + 1.25 -3 =

6.0 + 1.25 – 3.0 =

9.25

se fosse stato:

int a = 6 + 5/4 –3;

allora:

a = 9

PRECEDENZA RISPETTO AGLI ALTRI OPERATORI:

double d1 = 1.5;

double d2 = 1.5;

int i;

i = (int) (d1 + d2); ? 3

i = (int) d1 + d2; ? 2 (non 2.5 perchè tronca automaticamente il risultato poiché i è un int)

GLI OPERATORI LOGICI (LOGICA PROPOSIZIONALE)

espressione booleana = espressione il cui valore è TRUE o FALSE

il tipo boolean non esiste nell'ANSI C

ha 2 valori: TRUE (qualsiasi valore escluso 0), FALSE (0)

OPERATORI:

&& (Ù congiunzione) || (Ú disgiunzione) ! (Ø negazione)

qualsiasi espressione aritmetica può essere letta come espressione booleana:

if ( 3) then ... (3 ? 0 ? vero ? la esegue sempre)

con premesse false nessuno mi può contraddire (se mia nonna avesse le rotelle io sarei Napoleone)


x

y

x Ù y

t

t

t

t

f

f

f

t

f

f

f

f


x

y

x Ú y

t

t

t

t

f

t

f

t

t

f

f

f


x

Ø x

t

f

f

t


semantica di e1 && e2 (corrisponde alla moltiplicazione)

  1. valuto e1

  2. se e1 è FALSE restituisco FALSE (senza guardare la seconda espressione); se è TRUE valuto e2 e ne restituisco il valore

if ((a!=0.0) && (b/a<5.0))...

if ((b/a<5.0) && (a!=0.0))...

la prima funziona anche nel caso in cui x = 0.0 la seconda salta (division by 0)

semantica di e1 || e2 (corrisponde all'addizione)

  1. valuto e1

  2. se e1 è TRUE restituisco TRUE (senza guardare e2)

  3. altrimenti restituisco il valore di e2

è più forte l'operatore moltiplicativo ? ha la precedenza &&


es.

(x!=4)||(x!=18) quando vale TRUE?

se x è diverso da 4 restituisco TRUE

se x è pari a 4 ? x è diverso da 18 ? TRUE

vale TRUE per ogni valore di x


!((x==4) && (y=2*x)) quando vale TRUE?

è uguale a TRUE se “(x==4) && (y=2*x)” è FALSE

se x = 4 e y = 8 allora quest'ultima è vera; se x diverso da 4 la quest'ultima è falsa quindi la prima è vera (per tutti gli x diversi da 4)

IMPORTANTE:

L’assegnamento

a = i < 100;

è del tutto lecito, perché viene valutata l’espressione logica i <100, che può restituire 1 (true) o 0 (false). Il risultato e’ dunque un numero intero, che viene assegnato alla variabile, di tipo int, a.


Dato che le espressioni booleane restituiscono un risultato numerico, non esistono differenze tra le espressioni booleane e quelle aritmetiche ?

un’espressione può contenere una combinazione di operatori aritmetici, logici e relazionali.

es.

w = k + numero + (i < 100);

l’assegnamento viene effettuato alla fine, perché = ha la priorità più bassa


Essendo l’operatore di assegnamento trattato alla stregua degli altri,sarà lecita anche la seguente espressione:

i > n && (x = y)dove i > n;

è vera se il valore di i è maggiore di n; mentre x = y corrisponde all’assegnamento di y alla variabile x: in questo caso, se il valore di y è diverso da zero l’espressione (x = y) risulta vera altrimenti è falsa

CHAR

è un tipo aritmetico (caratteri trattati come se fossero numeri)

un char è un intero ristretto (ossia un intero a 8 bit, con valori da 0 a 255)

il tipo char è un insieme di valori (ASCII ? 256 valori ? posso rappresentare 256 caratteri; UNICODE ? 2^16 valori)

OPERATORI:

tutti quelli definiti sugli interi (interessano solo quelli relazionali)

STRUTTURA DI UN LISTATO C:

  1. inclusioni e definizioni (#include, #define)

  2. dichiarazioni globali:

  • di tipo

  • di variabile

  • di funzioni

  1. funzioni / procedure

dichiarazione (nome) diversa da definizione (legata all'allocazione di memoria)


<sequenza>=<comando><sequenza di comandi>

<dichiarazione>=<tipo><identificatore>;

<comando blocco>=

{

(<dichiarazione>)

<sequenza comandi>

}

Ritorna sopra | Home page