Panoramica del linguaggio C

Documenti analoghi
Unità Didattica 1 Linguaggio C. Fondamenti. Struttura di un programma.

Linguaggio C - sezione dichiarativa: costanti e variabili

Unità F1. Obiettivi. Il linguaggio C. Il linguaggio C++ Linguaggio C. Pseudolinguaggio. Primi programmi

Primi passi col linguaggio C

Corso di Fondamenti di Informatica Il sistema dei tipi in C++

Caratteristiche di un linguaggio ad alto livello

Il linguaggio C Il linguaggio C. Caratteristiche del C. Caratteristiche del C. Linguaggi di Programmazione I. Ferdinando Cicalese

Elementi lessicali. Lezione 4. La parole chiave. Elementi lessicali. Elementi lessicali e espressioni logiche. Linguaggi di Programmazione I

Struttura dei programmi C

ESECUZIONE DI PROGRAMMI C SU MACCHINE REALI. Docente: Giorgio Giacinto AA 2008/2009. formalizzazione degli algoritmi in linguaggio C

Introduzione al C. Introduzione. Linguaggio ad alto livello. Struttura di un programma C

ESECUZIONE DI PROGRAMMI C SU MACCHINE REALI. Docente: Giorgio Giacinto AA 2009/2010

Linguaggio C: introduzione

IL PRIMO PROGRAMMA IN C

Tipi di dati scalari (casting e puntatori) Alessandra Giordani Lunedì 10 maggio 2010

Laboratorio di Informatica Ingegneria Clinica Lezione 9/11/2011. Prof. Raffaele Nicolussi

Linguaggio C. Tipi predefiniti. Università degli Studi di Brescia. Prof. Massimiliano Giacomin. Prof. M. Giacomin

Somma di numeri binari

Linguaggio C Struttura dei programmi

Introduzione al Linguaggio C

Programmazione in Java (I modulo)

Il linguaggio C. Notate che...

Variabili. Unità 2. Domenico Daniele Bloisi. Corso di Programmazione e Metodi Numerici Ingegneria Aerospaziale BAER

Funzioni, Stack e Visibilità delle Variabili in C

Input/Output di numeri

Tipi di dato primitivi

Linguaggio C. Generalità sulle Funzioni. Variabili locali e globali. Passaggio di parametri per valore.

Gli Operatori. Linguaggio C. Gli Operatori. Esempi sull uso dell Operatore di Assegnamento. L Operatore di Assegnamento

Variabili. Tipi di dati di base. Variabili. Variabili

Analogico vs. Digitale. LEZIONE II La codifica binaria. Analogico vs digitale. Analogico. Digitale

Informatica (A-K) 7. Linguaggio C - 1

I.4 Rappresentazione dell informazione

Descrizione delle operazioni di calcolo. Espressioni costanti semplici

Sintassi: Per la dichiarazione di variabili dei tipi fondamentali:

La programmazione nel linguaggio C

Elementi di C++ di base

La codifica. dell informazione

Rappresentazione binaria delle variabili (int e char)

Le direttive del Preprocessore

Programmazione Orientata agli Oggetti. Emilio Di Giacomo e Walter Didimo

Tipi di dati fondamentali. Tipi di dati fondamentali. Utilità dei tipi di dati nelle dichiarazioni. Il tipo di dati char. Codice ASCII.

Laboratorio di informatica Ingegneria meccanica

Tipi di dato. Le variabili in C. Problema: dato in input un carattere, se esso è una lettera minuscola, trasformarla in maiuscola.

Il Linguaggio C. Caratteristiche. Caratteristiche. Esempio di programma in C. Tipi di dato primitivi in C. Dati

Introduzione al linguaggio C

La codifica. dell informazione

STORIA E CARATTERISTICHE

Rappresentazione dei numeri reali in un calcolatore

Una classe Borsellino. Tipi numerici di base - Costanti. Esempio d uso. Classe Borsellino cont d. Primi passi per l implementazione di Purse

La sintassi del C APPENDICE H

LA CODIFICA DELL INFORMAZIONE. Introduzione ai sistemi informatici D. Sciuto, G. Buonanno, L. Mari, McGraw-Hill Cap.2

Linguaggio C. Appunti per il corso di Laboratorio di Algoritmi e Strutture Dati. Stefano Aguzzoli

Linguaggio C. Tipi predefiniti e operatori. Università degli Studi di Brescia. Docente: Massimiliano Giacomin

Funzioni di I/O per numeri. Input e output di valori numerici. Input formattato scanf. Stream preesistenti

Codice binario. Codice. Codifica - numeri naturali. Codifica - numeri naturali. Alfabeto binario: costituito da due simboli

Espressione di chiamata di funzione

Programmazione I Paolo Valente /2017. Lezione 6. Notazione posizionale

modificato da andynaz Cambiamenti di base Tecniche Informatiche di Base

La "macchina" da calcolo

Appunti del corso di Informatica 1. 6 Introduzione al linguaggio C

Strutture dati e loro organizzazione. Gabriella Trucco

Linguaggio C Variabili e tipi di dato

Lezione 4. Sommario. L artimetica binaria: I numeri relativi e frazionari. I numeri relativi I numeri frazionari

Appunti del corso di Informatica 1 (IN110 Fondamenti) 6 Introduzione al linguaggio C

Il potere espressivo di un linguaggio è caratterizzato da: PROGRAMMA = DATI + CONTROLLO

VBA è un linguaggio di scripting derivato da Visual Basic, da cui prende il nome. Come ogni linguaggio ha le sue regole.

Rappresentazione dell Informazione

Sommario. Note alla traduzione... xix

Lab 02 Tipi semplici in C

Il Modello di von Neumann (2) Prevede 3 entità logiche:

Calcolo numerico e programmazione Rappresentazione dei numeri

Le funzioni, e le istruzioni di input/output

Laboratorio di Informatica Ingegneria Clinica Lezione 14-16/11/2011

Rappresentazione di Numeri Reali. Rappresentazione in virgola fissa (fixed-point) Rappresentazione in virgola fissa (fixed-point)

Mini-dispensa sui puntatori in C

LINGUAGGI DI PROGRAMMAZIONE!

Codifica. Rappresentazione di numeri in memoria

Variabili e Istruzioni

La codifica binaria. Fondamenti di Informatica. Daniele Loiacono

Lezione 10. L arte della programmazione

Corso sul linguaggio C Modulo Tipi di dato

Conversione di base. Conversione decimale binario. Si calcolano i resti delle divisioni per due

Lezione 3. I numeri relativi

Corso di Calcolatori Elettronici Un computer è un dispositivo in grado di eseguire dei calcoli e di prendere delle decisioni logiche.

Corso di Fondamenti di Programmazione canale E-O. Tipi di dato. Un esempio

La programmazione in linguaggio C

I sistemi di numerazione. Informatica - Classe 3ª, Modulo 1

Capitolo 4: Tabelle. y(x) = x 3 ì 2x. Capitolo 4: Tabelle 67. Nota: le tabelle non sono disponibili nel modo di rappresentazione grafica 3D.

Tipi elementari, costanti. Tipi di dati. VALORI: un insieme dei valori del tipo OPERAZIONI: per operare su tali valori. Tipi. intero reale carattere

Alfabeto ed elementi lessicali del linguaggio C

Un esempio per iniziare. Il controllo del programma in C. Altri cenni su printf() Esercizi (printf) printf( 8!=%d, fatt);

Tipi di dato. Il concetto di tipo di dato viene introdotto per raggiungere due obiettivi:

Fondamenti di Informatica T-1 Modulo 2

Preprocessore, linker e libreria standard

La codifica binaria. Informatica B. Daniele Loiacono

EXCEL software Excel .xlxs, La cella intestazione della colonna intestazione di righe l indirizzo della cella testo numeri formule

Aritmetica dei Calcolatori

Sistemi di numerazione

Rappresentazione dei Numeri

PROBLEMI ALGORITMI E PROGRAMMAZIONE

Transcript:

2 Panoramica del linguaggio C Obiettivi del capitolo Prendere confidenza con la struttura generale di un programma C e con i suoi elementi fondamentali Valorizzare la pratica di mettere commenti in un programma Capire l uso dei tipi di dato e le differenze tra i tipi int, double e char Imparare a dichiarare le variabili Capire come scrivere un costrutto di assegnamento per cambiare valore alle variabili Imparare il modo in cui il linguaggio C valuta le espressioni aritmetiche Imparare come acquisire i dati e visualizzare i risultati Imparare come scrivere stringhe di formato per l acquisizione dati e la visualizzazione dei risultati Imparare come utilizzare la redirezione per poter consentire l uso di file per l acquisizione dati e la visualizzazione dei risultati Capire le differenze tra errori di sintassi, errori di esecuzione ed errori logici, e imparare a evitarli e correggerli

32 Capitolo 2 Questo capitolo presenta C, un linguaggio di alto livello sviluppato nel 1972 da Dennis Ritchie presso gli AT&T Bell Laboratories. Poiché il linguaggio è stato pensato per la realizzazione del sistema operativo UNIX, inizialmente è stato impiegato per la programmazione di sistemi. Tuttavia, negli anni, la potenza e flessibilità del linguaggio, uniti alla ampia disponibilità di ottimi compilatori per sistemi di calcolo di qualsiasi livello e dimensione, hanno reso C un linguaggio popolare per una grande varietà di applicazioni. Questo capitolo presenta gli elementi di un programma C, i tipi di dato che possono essere gestiti e manipolati e i costrutti per acquisire dati, effettuare calcoli e visualizzare i risultati. 2.1 Gli elementi del linguaggio C Un vantaggio del linguaggio C è consentire di scrivere programmi che assomigliano al linguaggio quotidiano. Sebbene non sappiate ancora scrivere un programma, probabilmente siete in grado di comprendere il programma della Figura 1.13. La Figura 2.1 riporta lo stesso programma con evidenziate le caratteristiche di base di C, identificate qui nel seguito e poi illustrate in dettaglio dalla Sezione 2.2 alla Sezione 2.4. I numeri di riga riportati in tutte le figure che illustrano il codice non fanno parte del programma. Direttiva al preprocessore Macro costante Variabile Identificatore standard /* * Converti la distanza da miglia a chilometri. */ File header standard Commento #include <stdio.h> /* definizioni di printf, scanf */ #define KMS_PER_MILE 1.609 /* costante di conversione */ int Riservato main(void) { double miles, /* distanza in miglia */ kms; /* distanza equivalente in chilometri */ /* Acquisisci la distanza in miglia */ printf("enter the distance in miles> "); scanf("%lf", &miles); Commento Riservato } /* Converti la distanza in chilometri */ kms = KMS_PER_MILE * miles; Simbolo speciale /* Visualizza la distanza in chilometri */ printf("that equals %f kilometers.\n", kms); return (0); Punteggiatura Simbolo speciale Figura 2.1 Gli elementi del linguaggio C nel programma di conversione Miles-to-Kilometers.

Panoramica del linguaggio C 33 Direttive al preprocessore Il programma C della Figura 2.1 ha due parti: le direttive al preprocessore e il sottoprogramma principale. Le direttive al preprocessore danno istruzioni al preprocessore di C, un programma il cui compito è modificare il codice C prima che venga compilato. La direttiva al preprocessore inizia con il simbolo # come primo carattere della riga. Le due direttive più comuni sono presenti nella Figura 2.1: #include e #define. Il linguaggio C definisce esplicitamente solo un numero limitato di operazioni, mentre la maggior parte delle attività richieste da un programma non è definita direttamente. Ogni implementazione C contiene però una collezione di sottoprogrammi e simboli utili chiamate librerie. Lo standard ANSI (American National Standards Institute) C richiede che determinate librerie standard vengano fornite in ogni implementazione ANSI C. Un sistema C può ampliare il numero di operazioni disponibili fornendo librerie addizionali; un programmatore, inoltre, può creare ulteriori librerie di sottoprogrammi. Ogni libreria ha un file header (di intestazione) il cui nome ha estensione.h. La direttiva #include permette a un programma di accedere a una libreria: essa fa in modo che il preprocessore inserisca le definizioni presenti in un file di intestazione nel programma prima che questo venga compilato. La direttiva #include <stdio.h> /* definizioni printf, scanf */ notifica al preprocessore che alcuni nomi utilizzati nel programma (per esempio scanf e printf) sono presenti nel file di intestazione standard <stdio.h>. L altra direttiva al preprocessore presente nella Figura 2.1 #define KMS_PER_MILE 1.609 /* costante di conversione */ associa la macro costante KMS_PER_MILE al valore 1.609. Questa direttiva indica al preprocessore che ogni occorrenza di KMS_PER_MILE presente nel codice del programma C deve essere sostituita con 1.609 prima che la compilazione inizi. Ciò che si ottiene è che la riga kms = KMS_PER_MILE * miles; venga vista come kms = 1.609 * miles; nel momento in cui arriva al compilatore C. L uso della direttiva #define dovrebbe essere riservato a quegli aspetti che non cambiano mai (o raramente), perché durante l esecuzione di un programma non è possibile modificare il valore di una macro costante. D altra parte, l uso della macro costante KMS_PER_MILE nel codice del programma al posto del valore 1.609 rende più comprensibile e più facilmente manutenibile il programma. Il testo alla destra di ogni direttiva al preprocessore, che inizia con i caratteri /* e termina con i caratteri */, è un commento. I commenti offrono informazioni addizionali per una più facile comprensione del programma, e vengono ignorati sia dal preprocessore sia dal compilatore. Riquadro della sintassi per le direttive al preprocessore Per ogni nuovo costrutto C, proponiamo un riquadro che descrive e spiega la sintassi del costrutto, riportando esempi d uso. I riquadri seguenti descrivono i due tipi di direttive

34 Capitolo 2 al preprocessore. Gli elementi in corsivo presenti in ogni costrutto vengono discussi nella parte di interpretazione. Direttiva #include per definire identificatori da librerie standard SINTASSI: ESEMPI: #include <file di intestazione standard> #include <stdio.h> #include <math.h> INTERPRETAZIONE: la direttiva #include dice al preprocessore dove trovare il significato di identificatori standard utilizzati nel programma, collezionati in file chiamati file di intestazione standard. Il file di intestazione stdio.h contiene informazioni sui sottoprogrammi stardard di ingresso e uscita quali scanf e printf. Le descrizioni di sottoprogrammi matematici sono disponibili nel file di intestazione math.h. File di intestazione associati ad altre librerie standard saranno illustrati in capitoli successivi. Direttiva #define per creare macro costanti SINTASSI: #define NOME valore ESEMPI: #define MILES_PER_KM 0.62137 #define PI 3.141593 #define MAX_LENGTH 100 INTERPRETAZIONE: la direttiva #include dice al preprocessore di sostituire l identificatore NOME con valore. Le istruzioni del programma non possono modificare il valore associato a NOME. Sottoprogramma main L intestazione su due righe int main(void) individua l inizio del sottoprogramma principale chiamato sottoprogramma main (o semplicemente main) da cui inizia l esecuzione del programma. Ogni programma C ha un sottoprogramma main. Le rimanenti righe formano il corpo del sottoprogramma, che è delimitato dalle parentesi { e }. Il corpo di un sottoprogramma ha due parti: dichiarazioni e istruzioni eseguibili. Le dichiarazioni specificano al compilatore quante celle di memoria sono necessarie (per esempio miles e kms nella Figura 2.1). Per creare questa parte del sottoprogramma il programmatore utilizza i requisiti relativi ai dati del problema identificati durante la fase di analisi. Le istruzioni eseguibili (derivate dall algoritmo) vengono tradotte in linguaggio macchina e successivamente eseguite. Il corpo del sottoprogramma contiene punteggiatura e simboli speciali (*, =). Le virgole separano gli elementi di una lista, il punto e virgola compare al termine delle righe di codice e le parentesi graffe ({ }) individuano l inizio e la fine del corpo del sottoprogramma main.

Panoramica del linguaggio C 35 Definizione del sottoprogramma main SINTASSI: int main(void) { corpo } ESEMPIO: int main(void) { printf("hello world\n"); return (0); } INTERPRETAZIONE: l esecuzione del programma inizia dal sottoprogramma principale, main. Le parentesi racchiudono il corpo del sottoprogramma, che contiene dichiarazioni e istruzioni eseguibili. La riga int indica che il sottoprogramma restituisce un valore intero (0) al sistema operativo quando termina l esecuzione in modo normale. Il simbolo (void) indica che il sottoprogramma main non riceve alcun dato d ingresso dal sistema operativo nel momento in cui viene mandato in esecuzione. Termini riservati Ogni riga della Figura 2.1 contiene un certo numero di vocaboli classificati come termini riservati, identificatori di librerie standard e nomi di celle di memoria. Tutti i termini riservati sono scritti in minuscolo, hanno un significato speciale in C e non possono essere utilizzati per altri scopi. L Appendice E riporta una lista completa dei termini riservati del ANSI C, mentre in Tabella 2.1 sono riportati quelli usati nella Figura 2.1. Tabella 2.1 Termini riservati usati nella Figura 2.1. Termine riservato int void double return Significato Intero: indica che il sottoprogramma restituisce un dato di tipo intero. Indica che il sottoprogramma non riceve alcun dato dal sistema operativo. Indica che la cella di memoria contiene numeri reali. Il sottoprogramma restituisce il controllo del flusso d esecuzione al sistema operativo. Identificatori standard I rimanenti termini usati nella Figura 2.1 possono essere classificati in identificatori standard e identificatori definiti dall utente. Come per i termini riservati, gli identificatori standard hanno un significato speciale in C. Gli identificatori standard printf e scanf nella Figura 2.1 corrispondono ai nomi di operazioni definite nella libreria standard di sottoprogrammi di acquisizione/visualizzazione. A differenza dei termini riservati, gli identificatori standard possono essere ridefiniti dal programmatore e poi utilizzati per scopi diversi da quelli originali. Tuttavia la cosa è fortemente sconsigliata: se un identificatore standard viene ridefinito, non sarà più possibile utilizzarlo per il suo scopo originale nell ambito del programma.

36 Capitolo 2 Identificatori definiti dall utente Abbiamo scelto gli identificatori (chiamati identificatori definiti dall utente) per dare un nome alle celle di memoria che conterranno i dati e i risultati del programma e per dare un nome alle operazioni che vengono definite (come verrà spiegato nel Capitolo 3). Il primo identificatore definito nella Figura 2.1, KMS_PER_MILE, è il nome di una macro costante. C è un certo margine di libertà nella scelta degli identificatori: qui di seguito sono riportate le regole di sintassi e alcuni identificatori validi d esempio. La Tabella 2.2 mostra invece alcuni identificatori non validi. 1. Un identificatore consiste esclusivamente di lettere, cifre e _ (underscore, in italiano trattino basso ). 2. Un identificatore non può iniziare con una cifra. 3. Un termine riservato di C non può essere utilizzato come identificatore. 4. Un identificatore definito all interno di una libreria C standard non dovrebbe essere ridefinito. 1 Tabella 2.2 Identificatori non validi. Identificatore non valido 1Letter double int TWO*FOUR joe's Motivo Inizia con una cifra. Termine riservato. Termine riservato. Carattere * non ammesso. Carattere ' non ammesso. Identificatori validi letter_1, letter_2, inches, cent, CENT_PER_INCH, Hello, variable Sebbene le regole di sintassi non impongano un limite alla lunghezza, alcuni compilatori ANSI C non rilevano la differenza tra due identificatori se non c è una variazione nei primi 31 caratteri. Per esempio, i due identificatori r_capita_meat_consumption_in_1980 r_capita_meat_consumption_in_1995 verrebbero considerati identici da un compilatore C che ritiene significativi solo i primi 31 caratteri. La Tabella 2.3 elenca la categoria cui appartiene ogni identificatore utilizzato nel sottoprogramma della Figura 2.1. Tabella 2.3 Termini riservati e identificatori usati nella Figura 2.1. Termine riservato Identificatore standard Identificatore definito dall utente int, void, printf, scanf KMS_PER_MILE, main, double, miles, kms return 1 La regola 4 è piuttosto un suggerimento degli autori che non una regola di sintassi ANSI C.

Panoramica del linguaggio C 37 Lettere maiuscole e minuscole Chi scrive codice C deve prestare molta attenzione all uso di lettere maiuscole e minuscole poiché il compilatore le considera diversamente. I nomi Frequenza, frequenza, e FREQUENZA vengono considerati tre identificatori diversi. Per evitare di compiere errori è opportuno adottare uno schema coerente nell uso di lettere maiuscole e minuscole. In particolare, tutti i nomi dei sottoprogrammi di libreria standard utilizzano solamente lettere minuscole; uno stile largamente diffuso consiste nell usare per i nomi delle costanti macro solo lettere maiuscole. In questo libro adottiamo lo stesso schema e per gli altri identificatori useremo solo lettere minuscole. Stile di programmazione La scelta dei nomi degli identificatori In tutto il volume discuteremo di stile di programmazione in paragrafi specifici. Un bel programma è più leggibile e comprensibile rispetto a un programma trascurato. Si dice che, di solito, un programma viene scritto una volta sola e letto tantissime volte, frequentemente da persone diverse da chi l ha scritto, e spesso i programmatori passano più tempo a manutenere programmi (ossia ad aggiornarli e/o modificarli) che non a progettarli e a scriverli. Quindi, un programma scritto in modo pulito e chiaro semplifica il lavoro di tutti. Scegliete un nome significativo per gli identificatori introdotti, in modo tale che il loro scopo sia facilmente intuibile. Per esempio, un identificatore salario sarebbe ideale per memorizzare il salario percepito da una persona, mentre l identificatore s oppure sacco sarebbero scelte poco ragionevoli. Se un identificatore è costituito da due o più parole, l impiego del carattere underscore (_) tra le parole aumenta la leggibilità del nome scelto (euro_ora rispetto a euroora). Scegliete nomi lunghi a sufficienza da rendere il senso del valore memorizzato, ma cercate di non esagerare, perché più è lungo il nome più è possibile fare errori nello scriverlo. Per esempio, l identificatore kg_per_m2 è sufficientemente espressivo e più compatto di kg_per_metro_quadro. Quando si commette un errore di battitura e l identificatore scritto è identico al nome di un altro identificatore, il compilatore non può essere d aiuto. Per questo motivo è bene scegliere nomi di identificatori molto diversi tra loro, e soprattutto non usare identificatori che differiscono solo per l uso di lettere maiuscole e minuscole, come per esempio LARGO e largo. Infine, evitate di definire identificatori che differiscono solo per la presenza o assenza del carattere underscore (per esempio xcoord e x_coord). Esercizi per la Sezione 2.1 Autovalutazione 1. Quali identificatori tra quelli elencati sono (a) termini riservati di C, (b) identificatori standard, (c) utilizzati convenzionalmente come nomi di macro costanti, (d) identificatori validi generici, oppure (e) identificatori non validi? void MAX_ENTRIES double time G Sue's return printf xyz123 part#2 "char" #insert this_is_a_long_one 2. Perché è bene definire E (2.7182818) come una macro costante?

38 Capitolo 2 3. Quale parte di un sistema per la realizzazione di programmi in C cambia il testo di un programma C prima che venga compilato? Nominate due direttive che specificano tali modifiche. 4. Perché non si dovrebbe utilizzare un identificatore standard come nome di una cella di memoria generica in un programma? È possibile utilizzare per questo scopo un termine riservato? 2.2 Le dichiarazioni di variabile e i tipi di dato Dichiarazione di variabile In un programma, le celle di memoria utilizzate per memorizzare i dati di ingresso e i risultati del calcolo prendono il nome di variabili, poiché il valore in esse memorizzato può essere modificato (e solitamente lo è) durante l esecuzione. Le dichiarazioni di variabile in un programma C specificano al compilatore i nomi di tutte le variabili utilizzate e il tipo di informazione che vi verrà memorizzata e come essa sarà rappresentata in memoria. Le dichiarazioni di variabile double miles; /* input - distanza in miglia */ double kms; /* output - distanza in chilometri */ definiscono i nomi delle due variabili (miles e kms) utilizzate per memorizzare valori reali. Si noti che il compilatore C ignora i commenti posti a destra di ogni riga per spiegare lo scopo della variabile. La dichiarazione di variabile inizia con un identificatore (per esempio double) che specifica al compilatore C il tipo di dato (nello specifico un numero reale) memorizzato in una particolare variabile. È possibile dichiarare variabili di qualsiasi tipo. Il linguaggio C richiede che ogni variabile utilizzata nel programma venga prima dichiarata. Sintassi per le dichiarazioni SINTASSI: int lista_variabili; double lista_variabili; char lista_variabili; ESEMPI: int count, large; double x, y, z; char first_initial; char answer; INTERPRETAZIONE: per ogni nome nella lista_variabili viene allocata una cella di memoria. Il tipo di dato che verrà memorizzato (double, int, char) è specificato all inizio dell istruzione. Un istruzione può occupare più di una riga di codice. Lo stesso tipo di dato può apparire in più dichiarazioni: le due sezioni di dichiarazioni sottostanti sono di fatto ugualmente valide per la dichiarazione delle variabili frequency, time e years. double frequency, time; int years; double frequency; int years; double time;

Panoramica del linguaggio C 39 I tipi di dati Un tipo di dato definisce un insieme di valori e un insieme di operazioni a essi applicabili. Conoscendo il tipo di dato di un elemento (variabile o valore) il compilatore individua le operazioni che possono essere utilizzate. Ci sono tipi di dati standard, ossia predefiniti, quali per esempio char, double e int. I tipi standard double e int sono utilizzati come astrazioni per rappresentare e manipolare numeri reali e interi. I tipi di dati si applicano a variabili e costanti. Una costante numerica (o un numero) positiva in un programma C può essere scritta preceduta dal segno + o senza, indifferentemente, e una costante numerica non può contenere una virgola. (Nota: nel mondo anglosassone il simbolo separatore delle cifre decimali è il punto.) In C, i valori costanti sono interpretati sempre come numeri non negativi: quando in un programma viene scritto il numero 10500, il compilatore interpreta il segno meno come l operatore valore opposto, applicato alla costante positiva 10500, e non come parte integrante della costante. Il tipo di dato int Il tipo di dato int si usa per rappresentare i numeri interi relativi o, in breve, interi. Poiché lo spazio di memoria riservato è comunque finito, non è possibile rappresentare qualsiasi valore: lo standard ANSI C specifica che la finestra dei valori rappresentabili dal tipo di dato int deve includere almeno tutti i valori compresi tra 32767 e 32767. Dichiarata una variabile di tipo int, è possibile effettuare le comuni operazioni aritmetiche (somma, sottrazione, moltiplicazione e divisione) e il confronto tra due valori. Esempi di valori memorizzabili sono -10500 435 +15-25 32767 Il tipo di dato double Un numero reale è costituito da una parte intera e una parte frazionaria, separate dal punto decimale. Nel linguaggio C, il tipo di dato double si usa per rappresentare i numeri reali (per esempio 3.14159, 0.0005, 150.0). Dichiarata una variabile di tipo double, è possibile effettuare le comuni operazioni aritmetiche (somma, sottrazione, moltiplicazione e divisione) e il confronto tra due valori. È possibile utilizzare la notazione scientifica per rappresentare i numeri reali (tipicamente adottata per valori molto piccoli o molto grandi): il numero reale 1.23 10 5 rappresentato in notazione scientifica equivale a 123000.0, dove il valore 5 all esponente indica uno spostamento a destra di 5 posizioni. In C la notazione scientifica viene scritta come 1.23e5 oppure 1.23E5: la lettera e (oppure E) va interpretata come per 10 elevato a, quindi 1.23e5 significa 1.23 per 10 elevato a 5. Nel caso in cui l esponente sia negativo, il punto decimale va spostato a sinistra (per esempio, 0.34e-4 equivale a 0.000034). La Tabella 2.4 elenca qualche valore reale e indica quali di questi possono essere memorizzati utilizzati nel tipo di dato double. L ultima riga illustra come sia possibile utilizzare una costante double in notazione scientifica senza dover esplicitare il separatore decimale.

40 Capitolo 2 Tabella 2.4 Costanti di tipo double (numeri reali). Costanti di tipo double valide Costanti di tipo double non ammesse 3.14159 150 (manca il separatore decimale) 0.005.12345e (manca l esponente) 12345.0 15e-0.3 (0.3 non è un esponente valido) 15.0e-04 (equivale a 0.0015) 2.345e2 (equivale a 234.5) 12.5e.3 (.3 non è un esponente valido) 1.15e-3 (equivale a 0.00115) 34,500.99 (la virgola non è ammessa) 12e+5 (equivale a 1200000.0) Il tipo di dato double è un astrazione per la rappresentazione dei numeri reali, visto che non li include tutti: alcuni valori sono troppo grandi, altri troppo piccoli, altri infine non possono essere rappresentati in modo preciso a causa del numero finito di celle di memoria utilizzate. Tuttavia, l astrazione è sufficiente per permettere di rappresentare la maggior parte dei valori ed effettuare i calcoli necessari con una accuratezza adeguata. Tabella 2.5 Tipi di dati interi in C. Tipo Intervallo di valori in un calcolatore tradizionale short 32,767.. 32,767 unsigned short 0.. 65,535 int 2,147,483,647.. 2,147,483,647 unsigned 0.. 4,294,967,295 long 2,147,483,647.. 2,147,483,647 unsigned long 0.. 4,294,967,295 Le differenze tra tipi di dati numerici Potreste chiedervi perché sia necessario avere più di un tipo numerico. Non si potrebbe utilizzare il tipo double per qualsiasi valore numerico? In generale sì, ma su alcuni calcolatori, le operazioni su numeri interi vengono svolte più velocemente di quelle che manipolano numeri di tipo double. Inoltre, è necessaria una quantità di memoria minore per memorizzare dati di tipo int. Infine, le operazioni svolte su numeri interi calcolano il risultato preciso, mentre quando si utilizzano valori di tipo double può verificarsi un problema di accuratezza o un errore di arrotondamento. Questo dipende dal modo diverso utilizzato per rappresentare i valori numerici di tipo differente nella memoria del calcolatore: tutti i valori sono rappresentati in memoria mediante una sequenza binaria, ossia una sequenza di 0 e 1. Tuttavia, la sequenza binaria utilizzata per rappresentare il valore 13 di tipo int è diversa da quella utilizzata per rappresentare lo stesso valore di tipo double, ossia 13.0. Di fatto la rappresentazione interna dipende dall architettura del calcolatore e, in generale, i valori numerici double richiedono una quantità di memoria superiore rispetto ai valori numerici di tipo int. Nella Figura 2.2 è possibile confrontare i formati per i tipi int e double.

Panoramica del linguaggio C 41 Formato tipo int Formato tipo double Numero binario Segno Esponente Mantissa Figura 2.2 Formato interno per il tipo int e il tipo double. I numeri interi positivi vengono rappresentati nel sistema binario: il valore intero 13 viene rappresentato con il valore binario 01101. La notazione utilizzata per il tipo double (chiamata virgola mobile, o floating point) è simile alla notazione scientifica. La rappresentazione è costituita da tre sezioni: il segno (0 per valori positivi, 1 per quelli negativi), la mantissa e l esponente. La mantissa è una frazione binaria compresa tra 0.5 e 1.0. L esponente è un valore intero. Il valore di mantissa ed esponente sono tali per cui vale la seguente formula: numero reale = mantissa 2 esponente Se si utilizzano complessivamente 64 bit per rappresentare un valore di tipo double, 1 bit viene usato per il segno, 11 bit per l esponente e i rimanenti 52 per la mantissa. Poiché il numero di bit utilizzati è finito, non è possibile rappresentare in modo preciso qualsiasi valore di tipo double, come verrà discusso in seguito. I valori di tipo double possono avere una parte frazionaria, cosa non consentita ai valori di tipo int. Inoltre, il formato di tipo double consente di rappresentare una finestra di valori più ampia rispetto al formato di tipo int. Tale finestra dipende in realtà dalla specifica implementazione, ma lo standard ANSI per il linguaggio C specifica che per il tipo int deve essere possibile rappresentare almeno i valori positivi da 1 a 32767 (approssimativamente 3.3 10 4 ). Per i valori positivi di tipo double la finestra minima va da 10 37 a 10 37. Lo standard ANSI C mette a disposizione alcuni tipi per rappresentare i valori interi, oltre al tipo int. La Tabella 2.5 elenca i tipi di dati per la rappresentazione dei valori interi, specificando anche le finestre di valori rappresentabili con riferimento a un calcolatore tipico (short <= int <= long). Vale la pena notare che il valore più grande rappresentabile con un tipo unsigned integer è quasi il doppio del valore rappresentabile con il tipo signed. Questo dipende dal fatto che nel primo caso si dispone di un bit di più per rappresentare il valore, quello del segno, non utilizzato. Anche per rappresentare valori reali lo standard ANSI C definisce tre tipi, ciascuno dei quali richiede una diversa quantità di memoria: float, double e long double. I valori di tipo float devono avere una precisione di almeno 6 cifre (le prime 6 cifre della parte frazionaria devono essere corrette); la precisione per valori di entrambi i tipi double e long double deve essere di almeno 10 cifre decimali. La Tabella 2.6 elenca le finestre di valori positivi rappresentabili da ciascuno di questi tipi di dati, con riferimento a un calcolatore tipico. Il tipo di dato char Il tipo di dato char consente di rappresentare un singolo carattere: una lettera, una cifra o un simbolo speciale. Ogni valore di tipo char viene delimitato da apici (o apostrofi) singoli, come mostrato di seguito. 'A' 'z' '2' '9' '*' ':' '"' ' '