Sei sulla pagina 1di 10

2

Lindentazione del codice

Complementi - 1
Ver 2.4

2010 - Claudio Fornaro - Corso di programmazione in C

Lindentazione consiste nel precedere le righe di codice con un certo numero di spazi Ha lo scopo di evidenziare i blocchi di codice Ignorata dal compilatore, serve al programmatore per cogliere visivamente la struttura del programma Si indenti il codice mentre lo si sviluppa, non successivamente per renderlo bello Il numero di spazi sempre multiplo di un certo valore scelto come base (in genere 3 o 4) Normalmente si pu definire il tasto Tab in modo che introduca quel numero di spazi

Lindentazione del codice

Lindentazione del codice

Lindentazione esprime dipendenza, controllo: listruzione non indentata che precede il blocco controlla il blocco indentato Istruzione non Esempio: indentata for (i=0; i<10; i++) { scanf("%d", &a); Blocco indentato printf("%d\n", a*2); } Le due istruzioni scanf e printf sono controllate dallistruzione for precedente, la printf non controllata dalla scanf e per questo allo stesso livello (non indentata)

Esempio: for (i=1; i<100; i++) { printf("%d", i); if (i % 7 == 0) { printf(" divisibile per 7"); cont++; } printf("\n"); } Le istruzioni printf , if e printf del blocco del for sono allo stesso livello, il blocco dellif ulteriormente indentato

Lindentazione del codice


Lindentazione del codice

Lindentazione necessaria anche in assenza delle parentesi graffe (quando sono opzionali) Esempio: for (i=0; i<10; i++) for (j=0; j<20; j++) printf("%d,%d", i, j); Listruzione printf controllata dallistruzione for precedente che a sua volta controllata dallistruzione for pi esterna

Per il posizionamento delle parentesi graffe che racchiudono il blocco si suggerisce di utilizzare la modalit Kernighan-Ritchie 2a ed.:

la graffa di inizio blocco collocata sotto il primo carattere della parola chiave che controlla il blocco, in una riga a s stante tutte le istruzioni del blocco sono indentate (es. 4 spazi) la graffa di fine blocco allineata sotto quella di inizio blocco, in una riga a s

Ulteriori esempi di indentazione K&R2 corretta e coerente possono essere trovati in tutte le le soluzioni degli esercizi

Magic numbers

Magic numbers

Per chiarezza, si cerca di evitare/limitare la presenza di valori numerici nei programmi Si preferisce definire delle costanti Esempio errato (Che rappresenta quel 26? ): for (i=0; i<26; i++) printf("%c", 'A'+i); Esempio corretto: #define LETTERE_ALFAB 26 ... for (i=0; i<LETTERE_ALFAB; i++) printf("%c", 'A'+i);

Esempio errato (Che rappresenta quell 80 ?): int v[80]; for (i=0; i<80; i++) scanf("%d", &v[i]); Esempio corretto: define MAXVETT 80
...

int v[MAXVETT]; for (i=0; i<MAXVETT; i++) scanf("%d", &v[i]); MAXVETT auto-esplicativo, inoltre si ha un ulteriore vantaggio: se si vuole cambiare la dimensione del vettore nel programma sufficiente cambiare questa sola define

10

Uscita dal programma

Effetti collaterali

Il programma termina quando viene eseguita unistruzione return: return status; Possono esserci pi istruzioni return Nel main la return termina il programma e passa il valore status al S.O. per informarlo sullesito dellesecuzione:

Includendo <stdlib.h>, per status si possono usare le costanti EXIT_SUCCESS (al posto di 0) ed EXIT_FAILURE (generico 0)

il valore 0 indica che il programma ha eseguito quanto doveva: terminazione con successo valori diversi da 0 indicano che il programma ha avuto problemi (es. non ha trovato un file): terminazione con malfunzionamento

Unespressione pu produrre un risultato e/o dare effetti collaterali (side-effect ) Esempio x = 3 * i++; 3*i un calcolo che produce un valore, mentre i++ ha leffetto collaterale di incrementare i di 1 Quando tutti i side-effect di unespressione sono stati effettuati, si dice che si raggiunto un sequence point Prima del raggiungimento del sequence point, il valore delle variabili soggette ad side-effect indefinito e quindi non devono essere usate

11

12

Effetti collaterali

Effetti collaterali

In una stessa espressione quindi NON pu comparire pi di una volta una variabile soggetta a side-effect
Il sequence point viene raggiunto solo prima di passare allistruzione successiva, salvo:

Esempi di errori

dopo lesecuzione della prima parte delle espressioni contenenti gli operatori &&, ||, ?: e l'operatore virgola , quando vengono valutate le espressioni di while, for, do, if, switch e return dopo che tutti gli argomenti di una funzione sono stati valutati, ossia subito prima della chiamata alla funzione stessa

x = i++ * i++; lincremento/decremento postfisso non garantito venga effettuato subito dopo la valutazione (uso) della variabile: le due i potrebbero essere incrementate solo appena prima di passare allistruzione successiva (in questo caso x conterrebbe i elevato al quadrato) x = ++a / --a; In questo caso ci sono problemi di ordine di valutazione: non si sa a priori se lincremento viene effettuato prima del decremento o viceversa, i risultati possono dunque essere diversi su compilatori diversi v[i] = i++;

13

14

Ordine di valutazione

Ordine di valutazione

Le regole di precedenza tra gli operatori e le parentesi impongono solo un parziale ordinamento nella valutazione delle espressioni Ad esempio in unespressione come x = f() + g() * h(); viene calcolata prima la moltiplicazione e poi la somma, ma non noto in quale ordine le funzioni siano chiamate (e producano i valori) Per garantire un determinato ordine si usano variabili per mantenere i risultati intermedi Si pu talvolta utilizzare un costrutto che inserisce un sequence point (&&, ,, etc.)

Altri esempi di errori:

printf("%d %f\n", ++n, tan(1./n)); non si sa se viene prima valutata lespressione ++n e poi calcolata la funzione tan()o viceversa, quindi non si sa se il valore di n usato in tan() quello prima o dopo lincremento. La virgola che li separa non un operatore, ma un separatore e quindi non garantisce alcun ordine di valutazione x = sin(1/++x) + cos(1/++x); non noto se viene calcolata prima sin o prima cos, per cui gli argomenti di sin e cos possono essere diversi utilizzando compilatori diversi

15

16

Ordine di valutazione

Ordine di valutazione

Altri esempi di errori:

Altri esempi di errori:


in questi casi non noto se venga valutata prima la parte a sinistra o quella a destra delluguale, inoltre in una stessa espressione NON pu comparire pi di una volta una variabile soggetta a side-effect v[i] = ++i; v[i] = i++; non noto quale valore di i venga usato in v[i] v[++i] = ++i; non noto quale valore di i venga incrementato prima

x = sin(x++) + sin(x++); non noto quale delle funzioni sin venga calcolata prima; essendo uguali non importante, ma solo perch la chiamata a funzione inserisce un sequence point e quindi permette a x di essere riutilizzata nella stessa espressione x = i++ * i++; qui invece, non essendoci funzioni, non viene richiesto alcun sequence point, quindi NON accettabile x = v[++i] - v[++i]; non si sa quali siano gli indici effettivi delle due v[++i] in quanto non noto quale dei due venga valutato per primo prima di calcolare la sottrazione

17

18

Operatore virgola

Operatore virgola

Unisce due espressioni in ununica espressione Permette di inserire due espressioni dove sintatticamente ne prevista una sola: for (i=0, j=10; i<j ; i++, j--) Loperatore virgola inserisce un sequence point: lespressione di destra viene valutata solo dopo che lespressione di sinistra stata valutata completamente (side-effect terminati) Le due espr. possono essere di tipo diverso:

In un contesto dove la virgola ha il significato di separatore, per inserire loperatore virgola si includono questo e suoi operandi tra parentesi: funz(a, (b=1,b+2), c);
funz ha 3 parametri il secondo vale 3, b vale 1

Esempi x=2*4, 5*6;

il tipo e il valore dellespressione composta sono quelli dellespressione di destra il tipo e il valore dellespr. di sinistra sono scartati

x=8, 30 scartato (la prima espressione x=2*4, laltra 5*6) x=(2*4, 5*6); x=30, 8 scartato x=2*4, y=5*6; x=8, y=30 x=(2*4, y=5*6); 8 scartato, y=30, x=30 x=(y=2*4, 5*6); y vale 8, x = 30

19

20

Espressione condizionale

Espressione condizionale

E ununica espressione che pu assumere due valori in base ad una condizione x = (condizione) ? espr1 : espr2; equivale a: if (condizione) x = espr1; else x = espr2; condizione viene valutata completamente prima delle expr (inserisce un sequence point), le parentesi sono opzionali ma consigliabili per chiarezza Viene calcolata una sola delle due expr

Esempi

Il maggiore tra a e b: x = (a>b)?a:b; Il valore assoluto di a: x = (a>0)?a:-a; Il plurale di una parola printf("%d oggett%c\n", k, (k==1)?'o':'i');

21

22

Espressioni condizionali

Precedenza e associativit
() [] -> . ! ~ ++ + * & (cast ) sizeof * / % + - (somma e sottrazione) << >> < <= > >= == != & ^ | && || ?: = += = *= /= %= &= ^= |= <<= >>= , SD: da Sinistra a Destra, SD: da Dst. SD SD SD SD SD SD SD SD SD SD SD SD SD SD SD a Sin.

Il tipo del risultato sempre il pi capiente tra quelli prodotti dalle due expr (flag == 1) ? 11 : 12.0; restituisce sempre un valore double perch 12.0 un double mentre 11 un int (quindi restituisce 11.0 quando flag vale 1) Ha associativit da destra a sinistra: x=(a>b && a>c) ? a : (b>c)? b:c; equivale a: x=(a>b && a>c) ? a : ((b>c)? b:c); Un espressione condizionale non produce un L-value quindi non si pu scrivere: (a>b)?a:b = 12;

23

24

Big-endian e little-endian

Big-endian e little-endian

Indicano l'ordine in cui una sequenza di byte memorizzata nella memoria big-endian rappresenta un ordine in cui "big end" (il valore pi significativo nella sequenza) memorizzato prima (ad un indirizzo di memorizzazione pi basso) little-endian un ordine in cui "little end" (il valore meno significativo della sequenza) memorizzato prima Esempio: in un computer big-endian il num. esadecimale 2F82 memorizzato con 2F allindirizzo pi basso e 82 in quello pi alto

Nel formato little-endian alcuni calcoli sono pi semplici e veloci (quando un numero aumenta, si aggiungono byte per le cifre pi significative nella parte alta della memoria) I processori Intel sono little-endian Il TCP/IP memorizza i dati come big-endian (detto per questo anche network order) I processori Motorola sono big-endian I mainframe IBM e i supercomputer Cray sono big-endian

25

26

La funzione system

Operatori bitwise

Esegue un comando di shell E definita in <stdlib.h> Sintassi system(stringa_con_comando); Esempio Pulisce lo schermo system("CLS"); DOS/Windows system("clear"); Unix/Linux Esempio Sospende lesecuzione di un programma system("pause"); DOS/Windows

Operano su valori interi (con o senza segno) a livello dei singoli bit:
~ & | ^ << >> complemento a 1 AND bit a bit OR bit a bit EXOR bit a bit SHIFT a sinistra SHIFT a destra ~x x & y x | y x ^ y x << 2 x >> 2

Di solito si applicano a valori senza segno Hanno priorit inferiore agli oper. matematici Il risultato viene sempre convertito secondo le regole delle promozioni integrali (ad esempio, anche se x di tipo short, ~x di tipo int)

27

28

Operatori bitwise ~ << >>


Operatore bitwise &


Loperatore ~ inverte tutti i bit: ~0 d un valore int pari a 11..11 (1 in CA2) Gli operatori << e >> attuano uno shift del numero di posizioni indicato dalloperando di destra: y = x << 2; Il numero di posizioni deve essere maggiore o uguale a zero e strettamente minore del numero di bit delloperando di sinistra Loperatore << aggiunge sempre bit 0 a destra Loperatore >> aggiunge bit 0 a sinistra solo se x unsigned; se signed non definito Questi operatori hanno forma di assegnamento abbreviata: &= ^= |= <<= >>=

z = x & y; Ciascuno dei bit di z viene determinato calcolando lAND dei corrispondenti bit di x e y Loperatore & viene spesso usato per azzerare (unset o clear) alcuni dei bit di un valore dato (x) lasciando invariati gli altri Per specificare quali bit debbano essere azzerati si predispone una maschera da mettere in AND bit a bit con x

29

30

Operatore bitwise &

Operatore bitwise |

La maschera un numero intero, i bit del numero dato x in corrispondenza di bit a 0 della maschera vengono azzerati (mascherati, non passano attraverso la mashera), mentre quelli in corrispondenza di bit a 1 restano invariati (passano attraverso la maschera) Esempio y = x & 015; valore: x =2610 0..0110102 maschera: 158 0..0011012 risultato: y 0..0010002

z = x | y; Ciascuno dei bit di z viene determinato calcolando lOR dei corrispondenti bit di x e y Loperatore | viene spesso usato per impostare a 1 (set) alcuni dei bit di un valore dato (x) lasciando invariati gli altri Per specificare quali bit debbano essere impostati a 1 si predispone una maschera da mettere in OR bit a bit con x

31

32

Operatore bitwise |

Operatore bitwise ^

La maschera un numero intero, i bit del numero dato x in corrispondenza di bit a 1 della maschera vengono impostati a 1, mentre quelli in corrispondenza di bit a 0 restano invariati Esempio y = x & 012; valore: x =2210 0..0101102 maschera: 128 0..0011002 risultato: y 0..0111102

z = x ^ y; Ciascuno dei bit di z viene determinato calcolando lEXOR dei corrispondenti bit di x e y Loperatore ^ viene spesso usato per invertire alcuni dei bit di un valore dato (x) lasciando invariati gli altri Per specificare quali bit debbano essere invertiti si predispone una maschera da mettere in EXOR bit a bit con x

33

34

Operatore bitwise ^

Operatori bitwise e logici

La maschera un numero intero, i bit del numero dato x in corrispondenza di bit a 1 della maschera vengono invertiti, mentre quelli in corrispondenza di bit a 0 restano invariati Esempio y = x & 016; valore: x =2210 0..0101102 maschera: 168 0..0011102 risultato: y 0..0110002

Quando le espressioni collegate dagli operatori hanno solo valori 0 e 1, si potrebbero utilizzare gli operatori bitwise al posto degli operatori logici, ma:

la valutazione delle espressioni logiche non si ferma non appena il valore del risultato individuabile non c la garanzia di esecuzione da sinistra a destra degli operatori

Potrebbe invece essere utile utilizzare loperatore bitwise EXOR in quanto non esiste il corrispondente operatore logico

35

36

Esercizi
1. 2.

Homework 3-4
Metodo di ordinamento Radix Sort Per ordinare numeri interi positivi Lavora facendo riordinamenti parziali prima sulle unit, poi sulle decine, poi sulle centinaia, ecc. Esempio

3.

4.

Determinare di quanti bit composto un tipo char, short, int e long contando i bit. Visualizzare in binario il valore intero (decimale con segno) dato in input. Scrivere un programma che chieda un valore intero decimale, lo visualizzi in binario e calcoli quanti sono i bit pari a 1 che contiene. Scrivere un programma che chieda un valore decimale senza segno (da collocare in una variabile unsigned int) e ruoti i bit di n posizioni a sinistra o a destra a richiesta (ruotare i bit significa che quelli che escono da una parte entrano dallaltra).

Dati i valori: 7, 12, 9, 25, 36, 11, 20, 4 Scriverli utilizzando per tutti lo stesso numero di cifre: 07, 12, 09, 25, 36, 11, 20, 04 Definire una matrice avente per righe i valori delle cifre e per colonne i numeri dati Collocare i numeri sulla riga corrispondente alla cifra delle unit, ma nella stessa colonna

37

38

Homework 3-4
Collocamento dei valori in base alla cifra unit 07 12 09 25 36 11 20 04 0 20 1 11 2 12 3 4 04 5 25 6 36 7 07 8 9 09

Homework 3-4

Raccogliere i valori riga per riga e ricollocarli in base alla cifra decine

20

11

12

0 1 11 12 2 20 25 3 36 4 ................................

04 04

25

36

07 07

09 09

Raccoglierli nuovamente riga per riga (se ci fossero pi cifre loperazione andrebbe ripetuta sulle centinaia, sulle migliaia, etc.)

04

07

09

11

12

20

25

36

39

40

Homework 3
Si scriva un programma che realizzi il metodo di ordinamento Radix Sort di valori decimali (max 100 valori), considerando le singole cifre decimali come visto nellesempio, i valori vengano assegnati in decimale mediante scanf.

Homework 4
Scrivere un programma che realizzi il metodo di ordinamento Radix Sort di valori decimali (max 100 valori), considerando le singole cifre binarie del valore binario equivalente (utilizzare gli operatori bitwise sulle variabili), i valori vengano assegnati in decimale mediante scanf.

Potrebbero piacerti anche

  • 21 LongJmp
    21 LongJmp
    Documento3 pagine
    21 LongJmp
    Riccardo Ricci
    Nessuna valutazione finora
  • 15 Struct
    15 Struct
    Documento10 pagine
    15 Struct
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 07 Cicli
    07 Cicli
    Documento12 pagine
    07 Cicli
    openid_9xLqqfRO
    Nessuna valutazione finora
  • 02 LinguaggioC
    02 LinguaggioC
    Documento3 pagine
    02 LinguaggioC
    openid_9xLqqfRO
    Nessuna valutazione finora