Page 1

Identificatori e tipi di dati

Commenti /* commento su singola linea */ /* commento su linee multiple */ /* Questo e’ Un esempio di /* commento Innestato */ */

Non consentito in C (a differenza di Java)!

1


Commenti – C99 // commento su singola linea printf(“Hello world\n”); // commento a fine riga

Simili a Java…

Come commentiamo interi blocchi? „ „

Scomodo usare /* */ perche’ il blocco potrebbe contenere commenti Soluzione: direttiva di preprocessore #if „ „

Codice compilato se la condizione dopo #if è vera Blocco chiuso da #endif

#if 0 /*Commento prima del main*/ main() { for (int i = 0; i < 5; ++i) printf("%d e' il fattoriale di %d\n", fact(i),i); return 0; } #endif

2


Identificatori - I „

„

Costituiti da un numero qualsiasi di caratteri alfanumerici minuscoli o maiuscoli incluso “_” (underscore) Devono iniziare con una lettera o con un underscore „

„

Di solito identificatori che iniziano per “_” sono usati a scopo interno

Lunghezza: fino a 31 caratteri per variabili interne, garantiti 6 caratteri per nomi di funzioni e variabili esterne „ „

Dipende dalla macchina Ormai anche funzioni e variabili esterne possono avere nomi lunghi

Identificatori - II „

„

Convenzione: minuscole per variabili, maiuscole per costanti Il compilatore fà differenza tra lettere minuscole e maiuscole (case sensitive) „

„

Esempi validi: „

„

In generale il compilatore C è case sensitive! Ptr, ptr_ctr, ptr2ctr ptrCtr _ptr

Esempi non validi: „

10ptr, $date, ptr-ctr

3


Parole riservate „

„

Alcuni identificatori sono parole riservate (keywords) del linguaggio e pertanto non possono essere usate come nomi di variabili. Lista di keywords del linguaggio C: auto char do entry for int return static typedef void

break continue double extern goto long short struct union while

case default else float if register sizeof switch unsigned

Nomen est omen „

„

„

Bruno Caprile, Paolo Tonella: Nomen Est Omen: Analyzing the Language of Function Identifiers. WCRE 1999: 112-122 Gli identificatori costituiscono il mezzo primario per documentare il vostro software e renderlo comprensibile Studi in letteratura riportano che una cattiva scelta degli identificatori rende il codice „ „

Difficile da manutenere Maggiormente soggetto a errori

4


Per cui… Utilizzate identificatori significativi

„

Possibilmente, consistenti con il vocabolario del dominio d’interesse

„

Evitare:

„

Nome del proprio cane, fidanzato/a etc.: bob, jane, pluto Stati d’animo: uffa Sequenze casuali di caratteri: qwewn wqeu90qw8u Singole lettere: (ok per indici, meno bene per altre variabili)

„ „ „ „

Possiamo scrivere identificatori lunghi…

„

Parole composte usando camel case o under score

„

„

checkDate o check_date

Abbreviazioni e acronimi ok, ma con attenzione

„

ctr significa control o counter?

„

Dichiarazione di variabili „ „

„

„

classe_di_memoria tipo variabile1, variabile2,…; classe_di_memoria tipo variabile1=expr, variabile2=expr,…;

Un identificatore non è altro che il nome associato ad un oggetto Ogni variabile possiede due attributi che lo caratterizzano: „ „

„

„

classe di memoria tipo

La classe di memoria determina la durata in memoria dell’oggetto Il tipo determina il significato dei valori assunti dall’oggetto

5


Classi di memoria Classi di memoria piu’ importanti: automatica e statica

„

„

Ne esistono altre, le vedremo in seguito

Classe di memoria automatica: relativa agli oggetti locali ad un blocco che viene liberata non appena si raggiunge la fine di quel blocco Classe di memoria statica è relativa a

„

„

„

oggetti locali ad un blocco od esterni a qualsiasi blocco che non viene liberata tra uscite ed entrate successive tra diversi blocchi

Dichiarazione:

„

„

[auto | static] tipo variabile;

Default:

„

„ „

Classe automatica per variabili dichiarate in un blocco Classe statica per variabili dichiarate esterne a un blocco

Variabili interne ed esterne „

„

„

Variabili interne sono quelle dichiarate all’interno di una funzione Normalmente hanno vita limitata all’esecuzione della funzione stessa A meno che non siano dichiarate come static „

Vedremo esempi in seguito

6


Variabili interne ed esterne „ „ „

„

Le variabili esterne sono dichiarate all’esterno di funzioni Per cui, per default sono statiche Mantengono il valore memorizzato anche quando le funzioni che hanno usato tale variabile terminano Possono essere usate per scambiare dati tra funzioni „

„

Ma attenzione… limitate il piu’ possibile questo meccanismo, rende il codice illeggibile, e poco manutenibile

In realtà spesso usate per strutture dati insieme a funzioni che accedono/modificano tali strutture „

In mancanza delle classi e quindi delle variabili d’istanza, che avevamo in Java…

Esempio „

„

Scriviamo un programma che legge linee da STDIN e, alla fine, stampa la linea più lunga letta Dobbiamo „

„ „ „

Leggere una riga di testo per volta (caratteri fino a ‘\n’) Memorizzarla Calcolarne la lunghezza Se la lunghezza è maggiore di quella finora calcolata: „ „

Aggiornare il massimo Memorizzare in una variabile la riga più lunga

7


Soluzione #include <stdio.h> #define MAXLINE 1000 /* maximum input line size */ int max; /* maximum length seen so far */ char line[MAXLINE]; /* current input line */ char longest[MAXLINE]; /* longest line saved here */ int getline(); /* legge una riga da STDIN e la mette /* in line; restituisce la lunghezza */ void copy(); /* copia line in longest */

Soluzione (cont.) main() { int len; extern int max; extern char longest[]; max = 0; while ((len = getline()) > 0) if (len > max) { max = len; copy(); } if (max > 0) /* there was a line */ printf("%s", longest); return 0; }

8


Soluzione (cont.) int getline() { int c, i; extern char line[]; for (i = 0; i < MAXLINE - 1 && (c=getchar()) != EOF && c != '\n'; ++i) line[i] = c; if (c == '\n') { line[i] = c; ++i; } line[i] = '\0'; return i; }

Soluzione (cont.) void copy() { int i; extern char line[], longest[]; i = 0;while ((longest[i] = line[i]) != '\0')++i; }

9


Considerazioni… „

„

„

Quando una funzione utilizza variabili globali deve ri-dichiararle utilizzando la direttiva extern Di fatto, tale direttiva è opzionale se le variabili sono dichiarate all’interno dello stesso file sorgente E’ obbligatorio per utilizzare variabili/funzioni definite in altri file sorgenti „

Vedremo successivamente come realizzare programmi composti da più file sorgenti

Tipi di dati „ „

Le variabili devono essere dichiarate prima dell’uso Tipi base C „ „ „ „

„

„

char int float double

/* /* /* /*

carattere */ intero */ numero in virgola mobile */ float a doppia precisione */

Rappresentazione e numero di bit architecture dependent Valori tipici (ma dipendono dall’architettura!) „ „ „ „

char int float double

8 bit 16 bit (ormai 32 bit…) 32 bit 64 bit

10


Scope delle dichiarazioni „

„

In ANSI C90 le variabili dovevano essere dichiarate all’inizio di una funzione Ora (ANSI C99) è possibile avere interleave di dichiarazioni e altri statement #include <stdio.h> main() { int i=0; printf("i vale %d\n", i); int r=10; printf("r vale %d\n", r); return 0; }

„

Se compilo con gcc –pedantic mi da’ il warning: „

warning: ISO C90 forbids mixed declarations and code

Scope delle dichiarazioni – ANSI C99 „

In ANSI C99 è possibile dichiarare variabili „ „

„

In qualsiasi statement All’interno di un’espressione e.g. nell’inizializzazione di un ciclo for

Le variabili hanno visibilità all’interno del blocco in cui sono dichiarate „

Come Java…

11


Esempio #include <stdio.h>

i ivale vale00 i ivale vale11 i ivale vale22 i ivale vale33 i ivale vale44 Dopo Dopoililciclo cicloi ivale vale20 20

main() { int i=20; for(int i=0;i<5;i++) printf("i vale %d\n", i); printf("Dopo il ciclo i vale %d\n", i); return 0; } „

Devo compilare con l’opzione –std=c99 „

gcc interleave.c –std=c99 –o interleave.out

Esempio (2)

#include <stdio.h>

prima primadel delblocco bloccoi ivale vale20 20 nel nelblocco bloccoi ivale vale10 10 dopo dopoililblocco bloccoi ivale vale20 20

main() { int i=20; printf("prima del blocco i vale %d\n", i); { int i=10; printf("nel blocco i vale %d\n", i); } printf(“dopo il blocco i vale %d\n", i); return 0; }

12


Interi int a,b,c; „ Dopo che una variabile è stata dichiarata è possibile assgnarle un valore intero tramite l’operatore di assegnamento „ „

„

„

a = 100; O anche contestualmente alla dichiarazione int a=100, b,c=20;

Con un calcolatore che memorizza interi a 16 bit, i due valori estremi che possono essere assegnati ad un intero sono: -32768 +32767 Di fatto i moderni elaboratori usano 32 bit per gli interi

Caratteri char classe, sesso; „

„

„

in linguaggio C, i caratteri sono valori numerici ai quali per convenzione sono associate lettere dell’alfabeto, segni di interpunzione ed altri simboli alfanumerici. La codifica più comunemente usata è la codifica ASCII (American Standard Code for Information Interchange) Ad esempio la lettera ‘A’ viene codificata come 65 mentre la minuscola ‘a’ corrisponde a ‘97’

13


Dati in virgola mobile I dati floating point sono una approssimazione dei reali, espressi come frazioni decimali. 3.14159 2.71828 „ La loro rappresentazione interna dipende dalla macchina, ma di solito vengono utilizzati 32 bit, di cui almeno i primi 6 sono i più significativi. „ Il range di variazione dei floating point è (tipicamente): 2-9387e-39 1.7014e+38 „

Qualificatori „

„

Oltre alla classe di memoria e al tipo, è possibile specificare un qualificatore nella dichiarazione di una variabile Qualificatori del C „ „ „

„

short long unsigned

Dichiarazione completa: „

classe_memoria qualificatore tipo identificatore;

14


short e long „ „

Si applicano a interi (long anche ai double) short utilizza un numero di bit ridotto per rappresentare gli interi „ „ „

„

int a; /* intero */ short int a; /* intero short */ short a; /* int può essere omesso */

long utilizza un maggior numero di bit per rappresentare gli interi „ „

long int a; long a;

????? „

„

Quindi il significato di short e long non è definito, dipende dal compilatore Tuttavia esistono alcuni vincoli: „ „ „

„

short ≥ 16 bit long ≥ 32 bit short int ≤ int ≤ long int

Sulla mia macchina: „ „ „

short int: 16 bit int: 32 bit long int: 32 bit

15


signed e unsigned „ „

Si applicano a int e char signed indica che il tipo utilizza i bit disponibili per rappresentare interi positivi e negativi „ „ „

„

default per gli int Rappresentazione con complemento alla base signed char x; /* x potrà variare tra -128 e +127 */

unsigned indica che i bit disponibili sono utilizzabili per rappresentare numeri naturali „ „

„ „

Default per i char (valori tra 0 e 255) Se un signed int varia tra –x e x-1, un unsigned int varia tra 0 e 2*x-1 int a; unsigned int a;

/* a varia tra -2147483648 e 2147483647*/ /* a varia tra 0 e 4294967295 */

limits.h e float.h „

Contengono costanti che definiscono i range dei vari tipi utilizzati dal compilatore C „ „

per quell’architettura/sistema operativo tipicamente troverete questi files in /usr/include

„

CHAR_MIN, CHAR_MAX, INT_MIN, INT_MAX, SHRT_MIN, SHRT_MAX, LONG_MIN, LONG_MAX, UINT_MAX etc.

„

Estratto da limits.h:

#ifndef __INT_MAX__ #define __INT_MAX__ 2147483647 #endif #undef INT_MIN #define INT_MIN (-INT_MAX-1) #undef INT_MAX #define INT_MAX __INT_MAX__

16


Osserviamo i valori limite… #include<limits.h> main() { printf(“int varia tra %d e %d \n",INT_MIN,INT_MAX); printf(“unsigned int varia tra %d e %u \n",0,UINT_MAX); }

Operatore sizeof „

„

„

L’operatore sizeof restituisce il numero di byte utilizzati da una variabile, o del risultato di un’espressione Come vedremo in seguito è utilissimo per rendere i nostri programmi architecture independent Esempio: main() { int mesi,scorte,i; char anno; i = sizeof( mesi); i = sizeof(mesi)*sizeof(scorte); i = sizeof(char); }

17


Esercizio Utilizzando l’operatore sizeof(...) determinare e stampare la dimensione occupata dai seguenti tipi:

„

„ „ „ „ „ „ „

char int float double short int long int long double

Costanti „

In C esistono diversi tipi di costanti, in cui possiamo distinguere 5 tipi fondamentali: „ „ „ „ „

costanti intere costanti esplicitamente long costanti carattere costanti in virgola mobile stringhe di caratteri costanti

18


Costanti intere „

Costanti intere decimali 0, 1, 8, 10, 256

„

„

Costanti intere decimali long 2000000000L, -2000000000l, 2000000000l

„

„

Costanti intere decimali unsigned 3000000000U, 3000000000u

„

„

È possibile combinare unsigned e long 3000000000UL, 3000000000ul

„

Costanti ottali e esadecimali „

Costanti intere ottali (precedute da 0) „

„

Costanti intere esadecimali (precedute da 0x) „

„

„

0, 01, 010, 012, 0377 0x0, 0x1, 0xA, 0xC, 0xFF

E’ possibile usare i suffissi u e l anche per ottali e esadecimali main() Esempio: {

int a = a = a =

a; 0xA; 10; 012;

}

19


Costanti Carattere „

„

Una costante carattere è un carattere racchiuso da apici singoli Il valore della costante è il valore che la macchina associa a quel carattere nella particolare codifica usata (solitamente ASCII) ‘A’

‘x’

‘0’

‘$’

Costanti Carattere „

(Alcuni) caratteri speciali: „ „ „ „ „ „

„ „

New line (lf) Carriage return (cr) Backspace (bs) Horizontal tab (tab) Form feed (ff) Backslash (\)

‘\n’ ‘\r’ ‘\b’ ‘\t’ ‘\f’ ‘\\’

Il ritorno a capo in Unix è ‘\n’ mentre in Windows una sequenza di ‘\r’ e ‘\n’ Esercizio: scrivete un’utility dos2unix che converta un file di testo Windows in formato Unix

20


Costanti Double Una costante floating point è costituita da una parte intera, una parte decimale, una parte frazionaria e, opzionalmente, un esponente segnato intero:

„

„ „

127.0 0.235 2.E-16 2.56e+23 Necessaria la parte decimale se non usiamo la notazione esponenziale

Ogni costante floating point è rappresentata internamente come un numero in doppia precisione (double) Per usare la rappresentazione float usiamo il suffisso F o f:

„

„

„

127.0F 127.0f

Per usare la rappresentazione long double usiamo L:

„

„

127.0L 127.0l

Costanti Stringa „

„

„

„

„

Una stringa costante è una sequenza di uno o più caratteri racchiusi da doppi apici(“”). Il compilatore aggiunge un carattere NULL (‘\0’) alla fine di ogni stringa. Costanti stringa separate da spazi/ritorni a capo sono concatenate Il carattere “ (doppio apice) in una stringa va preceduto da \

Esempi „ „ „

„

char a[]=“Ciao Mondo”; char a[]= “Ciao” “ Mondo”; char a[]=“Ciao” “Mondo”; char a[]=“Titolo libro: \”Divina Commedia\””;

21


Enumerazioni „

„

Definiscono una lista di costanti associate a dei valori interi enum boolean { NO, YES }; „

„

Se come in questo caso semplicemente specifico il nome della costante (NO e YES), esse assumeranno numeri interi crescenti a partire da 0 .. quindi NO=0, YES=1

Enumerazioni - II „

La seconda possibilità è quella di definire un’enum assegnando esplicitamente valori alle costanti: „

„

enum escapes { BELL = '\a', BACKSPACE = '\b', TAB = '\t', NEWLINE = '\n', VTAB = '\v', RETURN = '\r' }; I caratteri sono valori leciti perché interi, i float no

22


Enumerazioni - III „

Se assegno valori a uno o più costanti nell’enum, gli elementi successivi assumeranno come valore gli interi successivi „

enum months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };

23

lez 2 2  

lezione 2 di programmazione

Read more
Read more
Similar to
Popular now
Just for you